سؤال

Consider you have an abstract base class A that is inheriting from other class X.

Class A override Method foo1.

There are few other classes A1,A2,A3 which are concrete classes.

All concrete classes inherit method foo1.

Method foo1 is almost like general algorithm that should be suitable for all concrete classes.
It is "almost" because of one exception in the algorithm there is an if condition, some of the classes lets say only A1,A3 need to luanch some other method foo2 in the start of foo.

For A2 we don't need to launch foo2.

The problem is if I that if I implement foo2 in class A all it's children will inherit this function as well, which is not so good design?

I thought of excluding foo2 to an Interface which will be implemented by concrete classes-> but this is not good as foo1 which calls foo2 is on the base class!

Any ideas how to solve this problem in a proper way?

Thank you

هل كانت مفيدة؟

المحلول

The solution I would use in that situation is make another layer of abstract classes that the classes that need the special Foo2 derive from instead.

abstract class A : X
{
    public virtual void Foo()
    {
        //Foo logic
    }
}

abstract class B : A
{
    protected virtual void Foo2()
    {
        //Foo2
    }

    override void Foo()
    {
        Foo2();
        base.Foo();
    }
}

public A1 : B
{
}

public A2 : A
{
}

public A3 : B
{
}

نصائح أخرى

You could have some kind of internal Foo1 Initializer that you can override in the child class.

public abstract class A {
    internal virtual void Foo1Init() {
        Console.WriteLine("Foo1Init");
    }

    public void Foo1() {
        Foo1Init();
        Console.WriteLine("Foo1");
    }
}

public class A1 : A {
    internal override void Foo1Init() {
        Console.WriteLine("A1 Foo1Init Override");
    }
}

public class A2 : A {

}

public class A3 : A {
    internal override void Foo1Init() {
        Console.WriteLine("A3 Foo1Init Override");
    }
}

class Program {
    static void Main(string[] args) {
        var a1 = new A1();
        a1.Foo1();

        var a2 = new A2();
        a2.Foo1();

        var a3 = new A3();
        a3.Foo1();

        Console.ReadKey();
    }
}

Output:

A1 Foo1Init Override  
Foo1  
Foo1Init
Foo1
A3 Foo1Init Override  
Foo1

Create a property in your base class that the subclasses can set when they need to have foo2() called:

public class BaseClass {
    protected bool RunFoo2 { get; set; }

    public BaseClass() {
        // Not really needed, since booleans default to false
        RunFoo2 = false;
    }

    public virtual void foo1() {
        if (RunFoo2)
            foo2();
        // Default code here
    }

    public virtual void foo2() {
        // Whatever
    }
}

public class A : BaseClass {
    public A() : base() {
        RunFoo2 = true;
    }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top