【问题标题】:Confused about interface inheritance对接口继承感到困惑
【发布时间】:2019-04-12 11:39:40
【问题描述】:

我知道我应该更广泛地使用它,但我们的代码只有少数几个接口,所以我对它们有点陌生。这是我的问题。在文件一中,我有这个:

Friend Interface IDateRow
    Property Name() As String
    ...
End Interface
Friend Interface IAmountRow
    Property StartDate() As IDateRow
    Property EndDate() As IDateRow
    ...
End Interface

在文件 2 中我有这个:

Friend Class DateRow
    Inherits DtaRow
    Implements IDateRow
    Friend Property Name() As String Implements IDateRow.Name
    ...
End Class

到目前为止一切顺利。现在...

Friend Class AmountRow
    Inherits DtaRow
    Implements IAmountRow
    Friend Property StartDate() As DateRow Implements IAmountRow.StartDate

这不起作用 - 它说:

'StartDate' cannot implement 'StartDate' because there is no matching property on interface 'IAmountRow'.

我是否认为这是因为它返回的是 DateRow 而不是 IDateRow? DateRow 实现了 IDateRow,因此它似乎应该是合法的。

我知道我在这里遗漏了一些愚蠢的东西......

【问题讨论】:

  • 您是否在输入Implements IAmountRow 后将光标移动到空行,而不是使用回车键? VB IDE 将在按下 Enter 键时自动实现界面。您可以将默认的Public 访问修饰符更改为Friend

标签: vb.net interface


【解决方案1】:

您必须使用与接口完全相同的类型来实现属性 - 所以

Friend Property StartDate() As DateRow Implements IAmountRow.StartDate

应该是

Friend Property StartDate() As IDateRow Implements IAmountRow.StartDate

【讨论】:

  • 好吧,我就是这么想的。但这似乎打破了继承和多态的整个概念。在我看来,接口的“整体思想”是您可以传递任何符合的对象,DateRow 符合,那么为什么这是一个问题?
  • 不,但我能理解这种困惑。它不会破坏多态性,它是多态性的一个例子,因为实现属性只需要提供一个实现IDataRow 的实例,这意味着它们可以返回任何实现IDataRow 接口的实例(无论是直接还是通过继承) - 但他们只能以IDataRow 的身份进行操作。
  • 我明白了。所以我想现在我想提出另一个问题,但我对术语感到困惑。我想你明白我想要做什么,你会如何描述这项任务?
【解决方案2】:

接口是一种身份。假设 IDateRow 位于“A.dll”中,实现它的 DateRow 位于“B.dll”中。并假设 A.dll 中有一个输入 IDateRow 实例的函数。由于 A.dll 没有引用 B.dll,所以它不知道 DateRow 是什么。因此,它需要一个具有“Property StartDate() As IDateRow”而不是 DateRow 的实例。

编辑 - 我试图回答@MauryMarkowitz 的评论:

我认为抽象类是你想要的。我用 c# 写了一个例子,但我猜它在 vb 中类似。

//A.dll -> has no reference
public abstract class Vehicle 
{
    public abstract double Mass();
    public abstract double Force();

    public double Acceleration()
    {
        return this.Force() / this.Mass();
    }
}
public interface ICar
{
    double MaxGroundSpeed();
}
public interface IPlane
{
    double MaxAirSpeed();
}


//B.dll -> has a reference to A.dll
public class Ferrari360 : Vehicle, ICar
{
    public override double Force()
    {
        return 400;
    }
    public override double Mass()
    {
        return 1350;
    }
    public virtual double MaxGroundSpeed()//Ferrari likes to make good cars, better, so this should be virtual.
    {
        return 282;
    }
}
public class Ferrari360GT:Ferrari360
{
    public override double Mass()
    {
        return 1100;
    }
    public override double MaxGroundSpeed()
    {
        return 300;
    }
}
public class Concorde : Vehicle, IPlane
{
    public override double Force()
    {
        throw new ClassifiedInformationException();
    }
    public override double Mass()
    {
        return 92080;
    }
    public double MaxAirSpeed()
    {
        return 2180;
    }
}
public class DeLoreanTimeMachine : Vehicle, ICar, IPlane
{
    public override double Force()
    {
        return 130;
    }
    public override double Mass()
    {
        return 1230;
    }
    public double MaxAirSpeed()
    {
        return 299792;
    }
    public double MaxGroundSpeed()
    {
        return 88;
    }
}

使用示例:

Ferrari360 greatCar = new Ferrari360();
Console.WriteLine(greatCar.Acceleration());

【讨论】:

  • 抱歉我的迟到回复......所以我只是做错了。我的目标是在 A 中有一个定义,在 B、C 和 D 中有不同的具体实现。A 中有对定义进行操作的函数,那么我如何在 B 中实现这些函数,以便可以调用它们一种?我猜是通过子类还是部分?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多