C# 继承接口方法的重新实现

C# 继承接口方法的重新实现,c#,inheritance,interface,extending,C#,Inheritance,Interface,Extending,我没有完全理解如何使用接口,所以我不得不问:-) 我使用基类,它实现IBaseClass接口。这些接口只包含一个声明: public interface IBaseClass { void Refresh (); } 因此,我在基类中实现了一个刷新方法: public void Refresh () { Console.WriteLine("Refresh"); } 现在我想使用一些从这些基类扩展而来的类,并实现IBaseClass接口:

我没有完全理解如何使用接口,所以我不得不问:-)

我使用基类,它实现IBaseClass接口。这些接口只包含一个声明:

public interface IBaseClass
{
    void Refresh ();
}
因此,我在基类中实现了一个刷新方法:

    public void Refresh ()
    {
        Console.WriteLine("Refresh");
    }
现在我想使用一些从这些基类扩展而来的类,并实现IBaseClass接口:

    public class ChildClass : BaseClass,IBaseClass
    {
    }
但由于在基类中实现了“刷新”,我不必再次实现该方法。我应该怎么做,强制将“刷新”实现到基类的所有child以及childclass的所有childclass中


多亏了kooki,您不能强制派生类以指定的方式重新实现该方法。您有三种选择:

  • 不要在基类中定义
    refresh
    。接口将强制子类实现它
  • 如果接口的唯一目的是强制实现,并将基类声明为
    抽象
    以及
    刷新
    ,则避免使用该接口,因为您不会给出实现
  • 在基类中将
    refresh
    定义为
    virtual
    。这允许覆盖,但不会强制覆盖。这就是
    ToString()
    的工作原理

  • 这都是假设您的基类大于单个方法。如果你的代码确实是你发布的代码,那么Oded的答案是最好的选择。

    简单。如果不提供基类实现,则必须在每个继承类中实现该方法

    实现这一点的一种方法是使
    基类


    如果您想提供一个默认实现,可以在基类中将其标记为virtual,这样您就可以在子类中重写该实现

    否则,在基类中将该方法标记为抽象的,这样子类就必须自己实现该方法

    我应该怎么做,强制将“刷新”实现到基类的所有child以及childclass的所有childclass中

    像这样:

    interface IBase
    {
        void Refresh();
    }
    
    abstract class BaseClass : IBase
    {
        public abstract void Refresh();
    }
    
    class ChildClass : BaseClass
    {
        public override void Refresh()
        {
            // Your code
        }
    }
    
    您甚至可以省略接口(我的经验法则是:如果接口仅由一个类实现,则转储该接口。不要坚持使用interfacitis。抽象类相当代表一个接口,另请参见)

    如果确实需要基类中的实现,请按如下方式构建:

    (abstract) class BaseClass ( : IBase)
    {
        public virtual void Refresh()
        {
            // Your code
        }
    }
    
    然后可以从派生类调用:

    public override void Refresh()
    {
        // Your code
    
        // optionally, to call the base implementation:
        base.Refresh();
    }
    

    可能是新的关键字可以帮助你做到这一点

    namespace ConsoleApplication1
    {
        interface IBase
        {
            void Referesh();
        }
        public class Base1 : IBase
        {
            public void Referesh()
            {
                Console.WriteLine("Hi"); 
            }
        }
        public class Class1 : Base1, IBase
        {
            public new void Referesh()
            {
                Console.WriteLine("Bye");
            }
    
        }
        class Program
        {
            static void Main(string[] args)
            {
                Class1 obj = new Class1();
                obj.Referesh();
    
                Console.ReadKey();
            }
        }
    }
    

    让我们一步一步来看看这个

    1:您有一个定义代码契约的接口,定义如下:

    public interface IBase
    {
        void Refresh();
    }
    
    2:您有一个实现接口的基类。(您会注意到刷新的实现是
    virtual
    。这允许您在派生类中重写此方法)

    3:您有一个从Base派生的超类。(您会注意到,派生类不需要显式实现
    IBase
    ,因为它是在较低的级别上实现的。我将向您展示您可以测试这个类的完整性)

    在这一点上,你可能在想;“好吧,那个么Child是如何实现IBase的?”。答案是它是通过Base间接实现的,因为
    Child
    继承了
    Base
    ,所以它也得到了
    IBase
    的实现

    因此,如果你要写:

    IBase instance = new Child();
    
    这是完全合法的,因为本质上,
    Child
    是从
    IBase
    间接派生而来的

    如果要测试此功能,可以在代码中执行此操作:

    bool canAssign = typeof(IBase).IsAssignableFrom(typeof(Child));
    //canAssign should be true as Child can be assigned from IBase.
    

    但我也需要在基类中实现。但是,如果没有其他的可能性,我将实现一个名为“BaseRefresh”的新方法,子类可以调用它interfaceimplementation@Kooki-为什么您也需要在
    基类中实现呢?因为有些字段必须设置为基类中的这些“刷新”不过,上面的代码是IBaseClass的精确复制。您可以这样做,但为什么要这样做?确切地说,抽象是解决方案,派生类中的接口重新实现可能很微妙:如果
    Base1
    明确地期望子类能够实现自己版本的
    刷新
    Base1
    应该将方法定义为
    virtual
    。这不是一个理想的解决方案,因为新关键字意味着方法隐藏。new关键字应用于定义原始方法/属性不是虚拟的(无法重写)新方法/属性实现。当你在设计类时,你知道该方法将被重写,然后将该方法设为虚拟方法。你为什么不接受我的答案?你找到更好的信息了吗?如果是,请发布并接受您自己的回复,以便将问题标记为已回答。
    class Child : Base
    {
        public override void Refresh()
        {
            base.Refresh(); //You can call this here if you need to perform the super objects Refresh() before yor own.
            //Add your implementation here.
        }
    }
    
    IBase instance = new Child();
    
    bool canAssign = typeof(IBase).IsAssignableFrom(typeof(Child));
    //canAssign should be true as Child can be assigned from IBase.