OOP设计:具有相同基类的不同操作的具体类

时间:2016-03-05 00:20:30

标签: c# .net oop object design-patterns

我想知道以下代码是否可以用C#编写:

AbstractClass a = new ConcreteClass1();
a.Operations.Method1();

AbstractClass b = new ConcreteClass2();
b.Operations.Method2();

其中Method1()是ConcreteClass1实例独有的,而Method2()是ConcreteClass2()实例独有的。因此,a.Operations.Method2()和b.Operations.Method1()将无效。

2 个答案:

答案 0 :(得分:1)

这在设计中是不可能的 - ab具有相同的类型,编译器会将它们视为这样。使其工作的唯一方法是使用运行时异常。

使用抽象类或接口的概念与您尝试执行的操作冲突;它听起来像ConcreteClass1ConcreteClass2不服务于相同的目的,它们是否仍然使用相同的抽象基类?

我不知道你到底想要做什么 - 所以我会提供一些选择:

使用接口显示特定类实现特定操作:

interface IOperation1
{
    void Operation1();
}

interface IOperation2
{
    void Operation2();
}

然后根据您要实现的目标引用接口。

如果应该同时调用Method1Method2,请考虑一个设计,其中AbstractClass声明要调用的方法,并且具体类基于以下内容执行不同的操作的是:

abstract class AbstractClass
{
   ...
   abstract void DoSomeOperation();
}

class ConcreteClass1 
{
   override void DoSomeOperation() 
   {
      this.Operations.Method1();
   }
}

class ConcreteClass2 
{
   override void DoSomeOperation() 
   {
      this.Operations.Method2();
   }
}

答案 1 :(得分:0)

ConcreteClass1ConcreteClass2可以使用不同的方法,但共享一些他们都从AbstractClass继承的功能。 (如果将它们作为基类型转换,则只能调用它们从基类型继承的常用方法。)

听起来,具体类使用Method1还是Method2是否是应在类内处理的内部细节之间的区别。该类应该知道它需要调用什么方法。事实上,该类的消费者是否需要知道它取决于Operations?可能不是。消费者应该只在类上调用一个方法,然后该类是否使用Operations.Method1Operations.Method2,或者甚至取决于Operations内部实现详情。

也许你想要的是这样的:

public abstract class AbstractClass
{
    public abstract void DoSomething();
}

public class Operations
{
    public void Method1()
    {
        //Does something
    }

    public void Method2()
    {
        //Apparently does something comopletely different
    }
}

public class ConcreteClass1 : AbstractClass
{
    private Operations _operations;

    public override void DoSomething()
    {
        _operations.Method1();
    }
}

public class ConcreteClass2 : AbstractClass
{
    private Operations _operations;

    public override void DoSomething()
    {
        _operations.Method2();
    }
}

Operations只应在基类中,如果需要 每个派生类都将使用它。 (这不会发生太多。如果所有派生类都具有相同的行为,为什么它不在基类中?)如果是这种情况那么你可以将它隐藏在基类中,如下所示:

public abstract class AbstractClass
{
    private Operations _operations;

    protected Operations Operations { get { return _operations; } }
    public abstract void DoSomething();
}

这样它就会暴露给派生类,但却隐藏在其他所有类中。