接口隐藏父类成员

时间:2015-11-17 18:03:23

标签: c# inheritance interface

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

请考虑以下内容,我无法访问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 herehere,但他们似乎关注的是如何使用新的,覆盖和虚拟关键字隐藏成员...对不起,但是我无法弄清楚这种情况如何适用。此外,我已经浏览了接口herehere上的MSDN API参考,但没有运气。

5 个答案:

答案 0 :(得分:4)

这里的问题特别与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的初始化对象。换句话说,单凭这一行,我们不知道它是ChildClassIMyInterface唯一已知的方法是MyProperty,因此我们知道的唯一方法是我们可以使用。

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

答案 1 :(得分:2)

这不是一个非常直接的原因:
IMyInterface没有DoSomething方法。

如果按如下方式修改界面,则代码将起作用。

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

答案 2 :(得分:1)

DoSomething()来自ParentClass,您正在使用IMyInterface引用。

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

((ChildClass) myClass).DoSomething();

((ParentClass) myClass).DoSomething();

答案 3 :(得分:0)

因为myClass的类型是IMyInterface

IMyInterface myClass = null;

IMyInterface没有DoSomething()方法:

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

然而,具有多态性,类型cal ParentClassChildClass。因此,您可以通过变形类型来使用该方法:

(myClass as ChildClass).DoSomething();

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

答案 4 :(得分:0)

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

接口是一个可以存在于任何类上的契约,无论它的继承链如何。您可以将该接口放在不从 ParentClass 继承的类上,并且该类必须满足的是接口中的内容(在您的情况下, MyProperty 属性)。如果您将 DoSomething()添加到界面,则此类也需要具有该方法。

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