简体   繁体   中英

Can you override one of the abstract methods in a base class with another base class?

I have a base class that has some abstract methods on it and there are 21 classes that are inheriting from this base class. Now for one of those abstract methods I want to implement it with a common implementation for 6 of the 21 classes so I thought about creating another base class that would do this.

I am open to suggestions but my main purpose of creating another base class between the current base class and the 21 classes is to keep from repeating the same code in 6 of the 21 classes if I didn't have to.

Here is a sample of code to illustrate the situation:

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

Yes, you can derive an abstract class from another abstract class

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
}

When we say it is optional to define the abstract methods of the parent class inside of the child class, it is mandatory that the child class should be abstract .

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

So I'm guessing that there will be 5 more classes like Another2 which inherits from AnotherBase that will have a common definition for OtherMethod

Yes, that is entirely possible and frequently done. There is no rule that says that you can have only one base class at the bottommost level of your class hierarchy; subclasses of that class can just as well be abstract and thereby become (somewhat more specialized) base classes for one group of classes indirectly derived from your general base class.

You should specify what exactly those classes do, but.. given the information you provided:

This is the exact problem that the Strategy pattern aims to solve, as shown in the example given in the Head First Design Patterns book.

You have an abstract Duck class, from which other ducks (eg, RedheadDuck , MallardDuck ) derive. The Duck class has a Quack method, that simply displays the string "quack" on the screen.

Now you are told to add a RubberDuck . This guy doesn't quack! So what do you do? Make Quack abstract and let the subclasses decide how to implement this? No, that'll lead to duplicated code.

Instead, you define an IQuackBehaviour interface with a Quack method. From there, you derive two classes, QuackBehaviour and SqueakBehaviour .

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

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

Now, you compose your ducks with this behaviour as appropriate:

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

You can even inject an instance of IQuackBehaviour through a property if you want the ducks to change their behaviour at runtime.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM