【问题标题】:OOP Design: Concrete Class having different Operations with Same Base ClassOOP 设计:具有相同基类的不同操作的具体类
【发布时间】:2016-03-05 00:20:29
【问题描述】:

我想知道下面的代码是否可以用 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() 将无效。

【问题讨论】:

  • 您是否尝试过将其输入 C# 并查看其作用?

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


【解决方案1】:

这在设计上是不可能的 - a 和 b 具有相同的类型,编译器会这样对待它们。使其工作的唯一方法是使用运行时异常。

使用抽象类或接口背后的概念与您尝试做的事情相冲突;听起来ConcreteClass1 和ConcreteClass2 的用途不同,它们是否仍应使用相同的抽象基类?

我不知道你到底想做什么 - 所以我将提供几个选项:

使用接口表明特定的类实现了特定的操作:

interface IOperation1
{
    void Operation1();
}

interface IOperation2
{
    void Operation2();
}

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

如果应该同时调用Method1 和Method2,考虑一个设计,其中AbstractClass 声明要调用的方法,具体类基于此执行不同的操作:

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

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

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

【讨论】:

    【解决方案2】:

    ConcreteClass1 和 ConcreteClass2 可以有一些不同的方法,但共享它们都继承自 AbstractClass 的一些功能。 (如果您将它们转换为它们的基类型,那么您只能调用它们从基类型继承的常用方法。)

    听起来具体类是使用Method1 还是Method2 之间的区别是应该在类内部处理的内部细节。该类应该知道它需要调用什么方法。事实上,该类的消费者是否甚至需要知道它依赖于Operations?可能不是。消费者应该只调用类上的方法,然后该类是否使用Operations.Method1、Operations.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();
    }
    

    这样它就暴露给派生类,但对其他所有东西都隐藏。

    【讨论】:

      猜你喜欢
      • 2011-05-18
      • 1970-01-01
      • 1970-01-01
      • 2017-10-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多