当子类继承父类和接口时,为什么子类不能访问父类方法?
请考虑以下内容,我无法访问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,但他们似乎关注的是如何使用新的,覆盖和虚拟关键字隐藏成员...对不起,但是我无法弄清楚这种情况如何适用。此外,我已经浏览了接口here和here上的MSDN API参考,但没有运气。
答案 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
的初始化对象。换句话说,单凭这一行,我们不知道它是ChildClass
。 IMyInterface
唯一已知的方法是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 也为ParentClass
或ChildClass
。因此,您可以通过变形类型来使用该方法:
(myClass as ChildClass).DoSomething();
与投射或变形对象类型的任何时候一样,请注意null
s。如果无法转换类型,则myClass as ChildClass
将为null
,因此上述结果将导致NullReferenceException
。
答案 4 :(得分:0)
理解这一点的最好方法是了解接口和父/子类之间的区别。
接口是一个可以存在于任何类上的契约,无论它的继承链如何。您可以将该接口放在不从 ParentClass 继承的类上,并且该类必须满足的是接口中的内容(在您的情况下, MyProperty 属性)。如果您将 DoSomething()添加到界面,则此类也需要具有该方法。
从父类继承的子类(子类)已建立关系。父类与它的子类共享它的非私有方法/属性/成员子集。因此,您可以将子类强制转换为其父类,并保留对这些属性的可访问性。