C# 需要帮助理解实现接口的抽象类吗

C# 需要帮助理解实现接口的抽象类吗,c#,inheritance,interface,abstract-class,C#,Inheritance,Interface,Abstract Class,考虑下面的例子。我有一个接口MyInterface,然后是两个抽象类MyAbstractClass1和MyAbstractClass2。MyAbstractClass1实现了MyInterface,但MyAbstractClass2没有实现 现在我有三个具体的课程 MyConcreteClass1派生自MyAbstractClass1,但未实现MyInterface MyConcreteClass2源于MyAbstractClass2,但实现了MyInterface MyConcreteClas

考虑下面的例子。我有一个接口MyInterface,然后是两个抽象类MyAbstractClass1和MyAbstractClass2。MyAbstractClass1实现了MyInterface,但MyAbstractClass2没有实现

现在我有三个具体的课程

  • MyConcreteClass1派生自MyAbstractClass1,但未实现MyInterface
  • MyConcreteClass2源于MyAbstractClass2,但实现了MyInterface
  • MyConcreteClass3源于MyAbstractClass1,并实现了MyInterface
  • ConcreteClass1是否也隐式实现MyInterface,因为它派生自MyAbstractClass1?假设MyAbstractClass1隐式实现了MyInteface的方法,那么ConcreteClass1不必强制转换到MyInterface来访问MyInteface方法,对吗

    MyAbstractClass1可以隐式实现MyInterface的方法作为抽象方法,但不能显式实现MyInterface的方法作为抽象方法。为什么会这样

    MyConcreteClass3是否过度,因为它正在实现一个已经由其基类实现的接口?即使您知道从MyAbstractClass1派生的所有类也应该实现MyInterface,您也会有这样做的原因吗

    这是一个类图

    代码如下:

    //interface
    public interface MyInterface
    {
        void MyMethodA();
        void MyMethodB();
        void MyMethodC();
    
    }
    
    //abstract classes
    public abstract class MyAbstractClass1 : MyInterface
    {
        public void MyMethodA()
        {
        }
    
    
        void MyInterface.MyMethodB()
        {
    
        }
    
        //Error: "the modifier abstract is not valid for this item"
        //abstract void MyInterface.MyMethodC();
    
        //This works
        public abstract void MyMethodC();
    
        public abstract void MyMethodZ();
    
    }
    
    
    public abstract class MyAbstractClass2
    {
        public void MyMethodX()
        {
        }
    
        public abstract void MyMethodY();
    
    }
    
    //Concrete classes
    //ConcreteClass 1: Only Abstract class implements the interface
    public class ConcreteClass1 : MyAbstractClass1
    {
        public override void MyMethodC()
        {
        }
    
        public override void MyMethodZ()
        {
    
        }
    }
    
    //ConcreteClass 1: Only Concrete class implements the interface
    public class ConcreteClass2 : MyAbstractClass2, MyInterface
    {
        public override void MyMethodY()
        {
        }
    
        public void MyMethodA()
        {
    
        }
    
        public void MyMethodB()
        {
    
        }
    
        public void MyMethodC()
        {
    
        }
    
    }
    //ConcreteClass 1: Both concrete and abstract class implement the interface
    public class ConcreteClass3 : MyAbstractClass1, MyInterface
    {
        public override void MyMethodC()
        {
    
        }
    
        public override void MyMethodZ()
        {
    
        }
    }
    

    在这种情况下,所有三个类都实现了接口(直接或间接)。这是因为MyAbstractClass1实现了MyInterface,而且由于MyConcreteClass1派生自MyAbstractClass1,因此也可以将MyConcreteClass1视为MyInterface。可以使用从MyAbstractClass1派生的东西来处理MyConcreteClass2,只要您将其视为MyInterface。由于MyAbstractClass1已经实现了MyInterface,所以在ConcreteClass3中从MyInterface派生的代码有点多余

    有了所有这些信息,我想说是的,在MyConcreteClass3上实现MyInterface是多余的,因为它源自已经实现MyInterface的MyAbstractClass1。 我认为您不能拥有接口方法的抽象实现的原因是它本身不提供代码,并且您不能保证它将在子类中被重写。改用虚拟的

    ConcreteClass1是否也隐式实现MyInterface,因为它派生自MyAbstractClass1

    ConcreteClass1不必强制转换到MyInterface来访问MyInterface方法,对吗

    对<代码>(myConcreteClass1是MyInterface)将评估
    true

    MyAbstractClass1可以隐式实现MyInterface的方法作为抽象方法,但不能显式实现MyInterface的方法作为抽象方法


    显式实现是区分重叠的成员签名。显式实现对于您在其上实现它的类是私有的,因此派生类无法访问它(因此不能是抽象的)。您也不能强制派生自MyAbstractClass1的类显式实现MyInterface,因此无法确保抽象成员永远都能实现

    MyConcreteClass3是否过度,因为它正在实现一个已经由其基类实现的接口?即使您知道从MyAbstractClass1派生的所有类也应该实现MyInterface,您也会有这样做的原因吗


    如果您需要显式实现接口的成员以将其与MyConcreteClass3上的重叠成员区分开来,则不一定如此。否则它是不必要的。

    它不是多余的。考虑这个类设置以简化…

    public interface I
    {
        void A();
    }
    
    public abstract class B : I
    {
        public void A( )
        {
            Console.WriteLine("Base");
        }
    }
    
    public class D : B
    {
        public void A()
        {
            Console.WriteLine("Hide");
        }
    }
    
    public class U
    {
        public void M(I i)
        {
            Console.WriteLine("M!");
        }
    }
    
    执行此

    var d = new D();
    var i = (I)d;
    var u = new U();
    
    i.A();
    d.A();
    u.M(d);
    u.M(i);
    
    你会得到

    Base
    Hide
    M!
    M!
    
    Hide
    Hide
    M!
    M!
    
    如果从派生类添加接口

    public class D : B, I
    {
      public void A()
      {
        Console.WriteLine("Hide");
      }
    }
    
    你会得到

    Base
    Hide
    M!
    M!
    
    Hide
    Hide
    M!
    M!
    

    因此,当您获得派生类的属性时,它会影响您获得的接口方法的哪个实现。

    “显式实现对您正在实现它的类是私有的”:实际上,它甚至比这更私有,因为您无法直接访问它。您必须首先强制转换到接口。并且使它有点公开,因为任何人都可以通过接口访问它。真的很奇怪,但仍然是一个很好的功能。