面向对象的设计之谜

时间:2013-07-31 21:01:37

标签: c# oop object-oriented-analysis

考虑您有一个继承自其他类X的abstract base class A.

A类覆盖方法foo1

其他类别A1,A2,A3很​​少是concrete类。

所有具体类都继承方法foo1

方法foo1几乎就像适用于所有具体类的通用算法一样 这是“差不多”的,因为算法中有一个例外是if条件,有些类只允许说A1,A3需要在foo2的开头用luanch其他方法foo

对于A2,我们无需启动foo2

问题是,如果我在A类中实现foo2,那么它的所有孩子都会继承这个函数,这不是很好的设计吗?

我想将foo2排除在将由具体类实现的接口上 - >但这并不好,因为调用foo1的{​​{1}}在基类上!

任何想法如何以正确的方式解决这个问题?

谢谢

3 个答案:

答案 0 :(得分:2)

您可以使用某种内部Foo1初始化程序,您可以在子类中覆盖它。

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();
    }
}

输出

A1 Foo1Init Override  
Foo1  
Foo1Init
Foo1
A3 Foo1Init Override  
Foo1

答案 1 :(得分:2)

我将在这种情况下使用的解决方案是创建另一层抽象类,而需要特殊Foo2的类来自。

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
{
}

答案 2 :(得分:0)

在基类中创建一个属性,子类可以在需要调用foo2()时设置该属性:

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;
    }
}