【问题标题】:Can you override one of the abstract methods in a base class with another base class?你能用另一个基类覆盖基类中的一个抽象方法吗?
【发布时间】:2014-03-12 15:00:12
【问题描述】:

我有一个基类,上面有一些抽象方法,并且有 21 个类继承自这个基类。现在对于其中一个抽象方法,我想用 21 个类中的 6 个的通用实现来实现它,所以我考虑创建另一个可以执行此操作的基类。

我愿意接受建议,但我在当前基类和 21 个类之间创建另一个基类的主要目的是避免在不必要的情况下在 21 个类中的 6 个中重复相同的代码。

这里有一个代码示例来说明这种情况:

public abstract class FooBase
{
   public abstract string Bar();
   public abstract string SomeMethod();
   public virtual string OtherMethod()
   {
       return this.SomeMethod();
   }
}

public abstract class AnotherBase : FooBase
{
   public abstract string Bar();
   public abstract string SomeMethod();
   public override OtherMethod()
   {
      //this is the common method used by 6 of the classes
      return "special string for the 6 classes";
   }
}

public class Foo1 : FooBase
{
   public override string Bar()
   {
      //do something specific for the Foo1 class here
      return "Foo1 special string";
   }
   public override string SomeMethod()
   {
      //do something specific for the Foo1 class here
      return "Foo1 special string";
   }
}

public class Another2 : AnotherBase
{
   public override string Bar()
   {
      //do something specific for the Another2 class here
      return "Another special string";
   }
   public override string SomeMethod()
   {
      //do something specific for the Another2 class here
      return "Another2 special string";
   }
}

【问题讨论】:

  • 你的想法似乎是正确的。你试过了吗?你遇到什么问题了吗?

标签: c# inheritance abstract-class


【解决方案1】:

是的,你可以从另一个抽象类派生一个抽象类

public abstract class FooBase
{
    //Base class content
}

public abstract class AnotherBase : FooBase
{
    //it is "optional" to make the definition of the abstract methods of the Parent class in here
}

当我们说在子类内部定义父类的抽象方法是可选时,子类必须是抽象的

public abstract class FooBase
{
    public abstract string Bar();
    public abstract string SomeMethod();
    public abstract string OtherMethod();
}

public abstract class AnotherBase : FooBase
{
    public override string OtherMethod()
    {
        //common method that you wanted to use for 6 of your classes
        return "special string for the 6 classes";
    }
}

//child class that inherits FooBase where none of the method is defined
public class Foo1 : FooBase
{
    public override string Bar()
    {
        //definition
    }
    public override string SomeMethod()
    {
        //definition
    }
    public override string OtherMethod()
    {
        //definition
    }
}

//child class that inherits AnotheBase that defines OtherMethod
public class Another2 : AnotherBase
{
    public override string Bar()
    {
        //definition
    }
    public override string SomeMethod()
    {
        //definition
    }
}

所以我猜还会有 5 个类,例如 Another2,它们继承自 AnotherBase,它们对 OtherMethod 有一个共同的定义

【讨论】:

【解决方案2】:

是的,这是完全可能的,而且经常这样做。没有规则说在类层次结构的最底层只能有一个基类;该类的子类也可以是抽象的,从而成为从您的通用基类间接派生的一组类的(更专业的)基类。

【讨论】:

    【解决方案3】:

    您应该具体说明这些类的作用,但是.. 鉴于您提供的信息:

    这正是 Strategy pattern 旨在解决的问题,如 Head First Design Patterns 书中给出的示例所示。

    您有一个抽象的 Duck 类,其他鸭子(例如,RedheadDuckMallardDuck)从该类派生。 Duck 类有一个 Quack 方法,它只是在屏幕上显示字符串“quack”。

    现在您被告知添加RubberDuck。这家伙不呱呱叫!所以你会怎么做?使Quack抽象并让子类决定如何实现它?不,这会导致重复代码。

    相反,您使用Quack 方法定义IQuackBehaviour 接口。从那里,您派生出两个类,QuackBehaviourSqueakBehaviour

    public class SqueakBehaviour: IQuackBehaviour
    {
        public void Quack(){
            Console.WriteLine("squeak");
        }
    }
    
    public class QuackBehaviour: IQuackBehaviour
    {
        public void Quack(){
            Console.WriteLine("quack");
        }
    }
    

    现在,你组合你的鸭子用这种行为适当:

    public class MallardDuck : Duck
    {
        private IQuackBehaviour quackBehaviour = new QuackBehaviour();
    
        public override void Quack()
        {
            quackBehaviour.Quack();
        }
    }
    
    public class RubberDuck : Duck
    {
        private IQuackBehaviour quackBehaviour = new SqueakBehaviour();
    
        public override void Quack()
        {
            quackBehaviour.Quack();
        }
    }
    

    如果您希望鸭子在运行时改变它们的行为,您甚至可以通过属性注入 IQuackBehaviour 的实例。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-11-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-17
      • 2012-12-04
      • 2015-02-25
      • 2019-08-31
      相关资源
      最近更新 更多