Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 基类实现接口 基类实现接口的缺点/风险是什么 总是在子类上实现接口更好吗_C#_.net_Oop - Fatal编程技术网

C# 基类实现接口 基类实现接口的缺点/风险是什么 总是在子类上实现接口更好吗

C# 基类实现接口 基类实现接口的缺点/风险是什么 总是在子类上实现接口更好吗,c#,.net,oop,C#,.net,Oop,你什么时候会用其中一个 public interface IFriendly { string GetFriendly(); } public abstract class Person: IFriendly { public abstract string GetFriendly(); } VS 嗯,你需要这样想: public interface IBreathing { void Breathe(); } //because every human br

你什么时候会用其中一个

public interface IFriendly
{
    string GetFriendly();
}


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


嗯,你需要这样想:

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() {}
}
关键是,只有当从基类派生的所有其他类都应该实现该接口时,才应该实现该接口(或继承,但仅将其定义公开为抽象)。 因此,在上面提供的基本示例中,只有当每个
人类
呼吸时(这里是正确的),才能使
人类
实现
IBreathing

但是!你不能让
Human
同时实现
IVillain
IHero
,因为这会让我们以后无法区分这两者。实际上,这样的实现意味着每个
人类
同时既是恶棍又是英雄

总结您问题的答案:

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

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

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

    如果从base one派生的每个类都应该实现该接口,那么它就必须实现

  • 您什么时候会使用其中一种?

    若从基类派生的每个类都应该实现这样的接口,那个么就让基类继承它。如果不是,则让具体类实现这样的接口


  • 从基类开始将您与基类的实现联系起来。我们总是一开始就认为基类正是我们想要的。然后我们需要一个新的继承类,但它不太适合,所以我们发现我们回到过去,修改基类以适应继承类的需要。这种事经常发生

    如果你从一个界面开始,那么你就有了更多的灵活性。不必修改基类,只需编写一个实现接口的新类即可。当类继承起作用时,您可以从中受益,但当类继承不起作用时,您不必依赖它

    当我第一次开始OOP时,我喜欢类继承。令人惊讶的是,它很少会变得实用。这就是校长的作用所在。最好从类的组合中构建功能,而不是将其嵌套在继承的类中


    还有一个原则。如果您可以继承,那很好,但是您不想回去更改基类(并冒着破坏其他内容的风险),因为新继承的类需要这样才能正常工作。编程到接口而不是基类可以保护您不必修改现有的基类。

    当所有派生类都将使用此实现时,在基类中实现;否则留下摘要。
    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() {}
    }