3

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

现在我有三个具体的类。

  1. MyConcreteClass1 派生自 MyAbstractClass1 但不实现 MyInterface。
  2. MyConcreteClass2 派生自 MyAbstractClass2,但确实实现了 MyInterface。
  3. MyConcreteClass3 派生自 MyAbstractClass1,并实现了 MyInterface。

ConcreteClass1 是否也隐式实现 MyInterface,因为它派生自 MyAbstractClass1?假设 MyAbstractClass1 隐式实现 MyInteface 的方法,那么 ConcreteClass1 不应该强制转换为 MyInterface 来访问 MyInteface 方法吗?

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

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

这是一个类图

替代文字 http://files.getdropbox.com/u/113068/abstractclassesandinterfaces.png

这是代码:

//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()
    {

    }
}
4

3 回答 3

3

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

是的。

ConcreteClass1 不应该强制转换为 MyInterface 来访问 MyInteface 方法吗?

正确的。(myConcreteClass1 is MyInterface)将评估true.

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

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

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

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

于 2009-07-10T00:19:35.693 回答
1

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

有了所有这些信息,我会说是的,在 MyConcreteClass3 上实现 MyInterface 是多余的,因为它派生自已经实现 MyInterface 的 MyAbstractClass1。我认为你不能有一个接口方法的抽象实现的原因是它本身不提供代码,你不能保证它会在子类中被覆盖。改用虚拟。

于 2009-07-10T00:12:34.847 回答
1

这不是多余的。考虑此类设置以简化...

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!

如果从派生类添加接口...

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

你会得到 ...

Hide
Hide
M!
M!

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

于 2009-07-10T00:26:11.187 回答