基类实现接口

6
  1. What are the cons/risks of base class implementing an interface?
  2. Is it better to always implement an interface on the sub-class?
  3. When would you use one or the other?

    public interface IFriendly
    {
        string GetFriendly();
    }
    
    
    public abstract class Person: IFriendly
    {
        public abstract string GetFriendly(); 
    }
    

    VS.

    public interface IFriendly
    {
        string GetFriendly();
    }
    
    public abstract class Person
    {
       // some other stuff i would like subclasses to have
    }
    
    public abstract class Employee : Person, IFriendly
    {
        public string GetFriendly()
        {
            return "friendly";
        }
    }
    

所有派生类都将使用此实现时,请在基类中实现;否则请保留为抽象。 - Pieter Geerkens
2个回答

14

嗯,你需要这样考虑:

public interface IBreathing
{
    void Breathe();
}

//because every human breathe
public abstract class Human : IBreathing
{
    abstract void Breathe();
}

public interface IVillain
{
    void FightHumanity();
}

public interface IHero
{
    void SaveHumanity();
}

//not every human is a villain
public class HumanVillain : Human, IVillain
{
    void Breathe() {}
    void FightHumanity() {}
}

//but not every is a hero either
public class HumanHero : Human, IHero
{
    void Breathe() {}
    void SaveHumanity() {}
}

重点是,只有每个从基类派生的其他类也应该实现接口(或继承但仅公开其定义作为抽象)时,您的基类才应该实现接口。

因此,根据上面提供的基本示例,仅当每个Human都呼吸时(在这里是正确的),您才会使Human实现IBreathing

但是!您不能使Human同时实现IVillainIHero,因为这样我们以后将无法区分它是一个还是另一个。 实际上,这种实现意味着每个Human都是恶棍和英雄。

总之,回答您的问题:

  1. 基类实现接口的缺点/风险是什么?

    如果每个派生自它的类也应该实现该接口,则没有任何问题。

  2. 在子类上始终实现接口是否更好?

    如果每个从基类派生的类都应该实现该接口,那就必须这样做。

  3. 什么情况下使用其中之一?

    如果每个从基类派生的类都应该实现此接口,请使基类继承它。 如果不是,使具体类实现此接口。


2
从一个基类开始会将你与基类的实现绑定在一起。我们总是开始认为基类正是我们想要的东西。然后我们需要一个新的继承类,但它并不完全适合,所以我们发现自己需要回到基类去修改以适应继承类的需求。这种情况经常发生。
如果你从一个接口开始,那么你就有更多的灵活性。而不是必须修改基类,你可以编写一个实现接口的新类。当它可行时,你可以获得类继承的好处,但当它不可行时,你并不受其限制。
我在开始使用面向对象编程时喜欢类继承。令人惊讶的是,它实际上很少被使用。这就是组合优于继承原则的应用。最好将功能构建为类的组合,而不是嵌套在继承类中。
还有开闭原则。如果你能够继承,那很好,但是你不想不得不返回去修改基类(并且有破坏其他东西的风险),因为它需要一个新的继承类才能正常工作。与其针对基类进行编程,不如针对接口进行编程,这样可以避免修改现有的基类。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接