【问题标题】:Interface hides parent class member接口隐藏父类成员
【发布时间】:2015-11-17 18:03:23
【问题描述】:

当子类同时继承父类和接口时,为什么子类不能访问父类方法?

考虑以下情况,我无法访问 DoSomething() 方法。

class Program
{
    static void Main(string[] args)
    {
        IMyInterface myClass = null;
        myClass = new ChildClass();
        // this returns error
        myClass.DoSomething();
    }
}

internal class ParentClass
{
    public ParentClass() { }

    public void DoSomething() { }
}

internal class ChildClass : ParentClass, IMyInterface
{
    public string MyProperty { get; set; }

    public ChildClass() : base() { }
}

internal interface IMyInterface
{
    string MyProperty { get; set; }
}

我查看了 SO 讨论 here 和 here,但他们似乎关注如何使用 new、override 和 virtual 关键字隐藏成员......抱歉,但我不知道如何适用于这种情况。此外,我浏览了接口 here 和 here 上的 MSDN API 参考,但没有运气。

【问题讨论】:

  • 因为您将myClass 声明为IMyInterface,它没有DoSomething 的定义。

标签: c# inheritance interface


【解决方案1】:

这里的问题与您的 Main 方法中的变量声明有关。

    IMyInterface myClass = null;
    myClass = new ChildClass();
    // this returns error
    myClass.DoSomething();

孤立地看台词,我们可以将其简化为这样。

    IMyInterface myClass = null;

    // BLAH BLAH myClass gets initialized somehow, we don't know/care how.

    myClass.DoSomething();

所以到那时,我们只知道我们有一个接口IMyInterface的初始化对象。换句话说,单看这条线,我们不知道它是ChildClass。 IMyInterface 的唯一已知方法是 MyProperty,所以这是我们知道唯一可供我们使用的方法。

您可以通过将 myClass 明确声明为 ChildClass 实例来解决此问题。您甚至可以在期望返回 IMyInterface 类型的方法中返回此变量。

【讨论】:

  • 感谢您提供额外的分步说明。
【解决方案2】:

这不起作用的原因很简单:
IMyInterface 没有 DoSomething 方法。

如果你修改你的界面如下,你的代码就可以工作了。

internal interface IMyInterface
{
    string MyProperty { get; set; }
    void DoSomething();
}

【讨论】:

  • 你确定只是改变界面就能“让它工作”吗?子类必须显式实现接口,因为父类不会自动实现接口,因为它们具有相同的名称/参数...
  • @RonBeyer ChildClass 继承自 ParentClass,它有一个 public void DoSomething() 方法。所以ChildClass 确实完全实现了修改后的IMyInterface。
  • 有趣,我没有意识到你可以投射这样的接口,因为它没有在基类上标记为虚拟或抽象,并且基类没有实现接口。
【解决方案3】:

DoSomething() 来自 ParentClass,您使用的是 IMyInterface 引用。

要使用此方法,您需要进行强制转换:

((ChildClass) myClass).DoSomething();

或

((ParentClass) myClass).DoSomething();

【讨论】:

    【解决方案4】:

    因为myClass的类型是IMyInterface:

    IMyInterface myClass = null;
    

    而IMyInterface 没有DoSomething() 方法:

    internal interface IMyInterface
    {
        string MyProperty { get; set; }
    }
    

    然而,对于多态性,类型可也为ParentClass 或ChildClass。所以你可以通过变形类型来使用该方法:

    (myClass as ChildClass).DoSomething();
    

    与任何时候投射或变形对象的类型一样,请注意nulls。如果无法转换类型,则myClass as ChildClass 将是null,因此上述结果将导致NullReferenceException。

    【讨论】:

      【解决方案5】:

      理解这一点的最好方法是了解接口和父/子类之间的区别。

      接口是一种契约,可以存在于任何类上,无论其继承链如何。您可以将该接口放在不从 ParentClass 继承的类上,而该类所要满足的就是您的接口中的内容(在您的情况下,MyProperty财产)。如果您将 DoSomething() 添加到接口,则该类也需要具有该方法。

      从父类继承的子类(子类)建立了关系。父类与其子类共享它的非私有方法/属性/成员子集。因此,您可以将子类强制转换为它的父类并保留对这些属性的可访问性。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-07-14
        • 1970-01-01
        • 2015-06-20
        • 1970-01-01
        • 1970-01-01
        • 2017-10-21
        • 2012-03-01
        相关资源
        最近更新 更多