接口继承。不实现接口错误

时间:2017-02-28 13:56:17

标签: c# inheritance interface

使用继承接口时遇到问题。我将在下面的例子中解释我的问题。假设我有接口IFlyable

public interface IFlyable
{
    IVerticalSpeed Speed { get; set; }
}

它包含IVerticalSpeed接口。我创建了另一个名为ISpeed的接口,它继承自IVerticalSpeed接口:

public interface ISpeed : IVerticalSpeed
{
    int MaxSpeed { get; set; }
}

在下一步中,我创建了一个实现Fly接口的类IFlyable

public class Fly : IFlyable
{
    public IVerticalSpeed Speed { get; set; }
}

一切都很好......但如果我想将IVerticalSpeed接口替换为继承自ISpeed接口的IVerticalSpeed接口,该怎么办?

public class Fly : IFlyable
{
    public ISpeed Speed { get; set; }
}

我认为一切都应该没问题,因为我的ISpeed接口是IVertialSpeed接口+ ISpeed接口contatins的任何东西。但那是不对的。我得到的错误是:“Fly没有实现接口成员IFlyable.Speed(...)。为什么?

5 个答案:

答案 0 :(得分:2)

所有答案都显示了可能的解决方案,但实际上没有人回答这个重要问题:

  

我认为一切都应该没问题,因为我的ISpeed接口是IVertialSpeed接口+ ISpeed接口contatins的任何东西。但那是不对的。我得到的错误是:" Fly没有实现接口成员IFlyable.Speed(...)。的为什么吗

你自己说过了。 ISpeedIVerticalSpeed,但并非所有IVerticalSpeed都是ISpeed,因此您根本不满足合同。

如果您的代码被允许并且我想执行以下操作会发生什么:

public interface IMyOtherSpeed: IVerticalSpeed { ... }
IFlyable myFly = new Fly();
IMyOtherSpeed mySpeed = new MyOtherSpeed();

myFly.Speed = mySpeed; //Runtime error, mySpeed is not an ISpeed?!?

你现在看到了这个问题?您违反了界面合同,因为当您的班级接受任何 ISpeed时,您的班级才会接受IVerticalSpeed

答案 1 :(得分:1)

如果您使用泛型,您可以执行类似

的操作
public interface IFlyable<out T> : where T IVerticalSpeed
{ T Speed {get;set;} }

然后在你的课堂上你会做类似

的事情
public class Fly : IFlyable<SomeSpeedClass>
{
  public SomeSpeedClass Speed{get;set}
}

答案 2 :(得分:1)

因为您的媒体签名必须保持100%相同。您可以实施新属性,作为解决方法。但它也有其局限性。

如果您的继承可以双向工作,可以执行此操作。您已经知道,所有ISpeed都是IVerticalSpeed。但事实并非如此。并非所有IVerticalSpeed都是ISpeed。因此,我们可以为您的课程提供另一种方法,但在这一点上它将面临一个问题:

  public interface IVerticalSpeed
  {
    int Value { get; set; }
  }

  public interface IFlyable
  {
    IVerticalSpeed Speed { get; set; }
  }

  public interface ISpeed : IVerticalSpeed
  {
    int MaxSpeed { get; set; }
  }

  public class Fly : IFlyable
  {
    public ISpeed Speed { get; set; }

    IVerticalSpeed IFlyable.Speed
    {
      get
      {
        return this.Speed;
      }
      set
      {
        // Wow, wait, you want to SET an IVerticalSpeed,
        // but not every IVerticalSpeed is an ISpeed... what now?
        // this.Speed = value;
      }
    }
  }

这不是代码问题,这是一个设计问题。如果有人为您IVerticalSpeed设置Fly,您想做什么?因为您的界面说明了这一点。也许你不想要制定者?

答案 3 :(得分:0)

而不是

public class Fly : IFlyable
{
    public ISpeed Speed { get; set; }
}

您应该匹配IFlyable界面

public class Fly : IFlyable
{
    public IVerticalSpeed Speed { get; set; }
}

接口不是继承,必须完全匹配。

编辑:让我重新说一下,实现其他接口的接口不是继承,因此错误。接口必须与我完全匹配,这就是它引发错误的原因(ISpeed!= IVerticalSpeed)

答案 4 :(得分:0)

您还没有显示IVerticalSpeed,但如果您能控制它,请考虑

public interface IFlyable<out TSpeed>
    where TSpeed : IVerticalSpeed
{
    TSpeed Speed { get; set; }
}

然后在Fly这样实现

public class Fly : IFlyable<ISpeed>
{
    public ISpeed Speed { get; set; }
}