C# 需要帮助理解实现接口的抽象类吗
考虑下面的例子。我有一个接口MyInterface,然后是两个抽象类MyAbstractClass1和MyAbstractClass2。MyAbstractClass1实现了MyInterface,但MyAbstractClass2没有实现 现在我有三个具体的课程C# 需要帮助理解实现接口的抽象类吗,c#,inheritance,interface,abstract-class,C#,Inheritance,Interface,Abstract Class,考虑下面的例子。我有一个接口MyInterface,然后是两个抽象类MyAbstractClass1和MyAbstractClass2。MyAbstractClass1实现了MyInterface,但MyAbstractClass2没有实现 现在我有三个具体的课程 MyConcreteClass1派生自MyAbstractClass1,但未实现MyInterface MyConcreteClass2源于MyAbstractClass2,但实现了MyInterface MyConcreteClas
//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!
因此,当您获得派生类的属性时,它会影响您获得的接口方法的哪个实现。“显式实现对您正在实现它的类是私有的”:实际上,它甚至比这更私有,因为您无法直接访问它。您必须首先强制转换到接口。并且使它有点公开,因为任何人都可以通过接口访问它。真的很奇怪,但仍然是一个很好的功能。