我们有A和B两类,B源自A,
我创建了A a = new B();
为什么在我的代码中调用不包含A的B方法时出现错误。
这是否意味着类型对象指针是A类型?其次,为什么当我调用SomeMethod
时,它调用的是A而不是B的方法?
在这种情况下在堆中创建对象实例时,类型对象指针指向A还是B?
class A
{
public void SomeMethod()
{
Console.Write("This is A");
}
}
class B : A
{
public void SomeMethod()
{
Console.Write("This is B");
}
public void OtherMethod()
{
Console.Write("This is New method");
}
}
class Program
{
static void Main(string[] args)
{
A a = new B();
a.SomeMethod(); // This is A method
a.OtherMethod(); // I get error here that a does not contain definition for this method
}
}
答案 0 :(得分:2)
因为您没有在IDE中看到明显的警告
严重性代码描述项目文件行抑制状态 警告CS0108'B.SomeMethod()'隐藏继承的成员 'A.SomeMethod()'。如果打算隐藏,请使用new关键字。
Compiler Warning (level 2) CS0108
'member1'隐藏继承的成员'member2'。如果使用新关键字 隐藏是故意的。
声明一个变量,其名称与基变量相同 类。但是,未使用new关键字。此警告通知您 您应该使用new将该变量声明为好像已经有new 在声明中使用。
如果要隐藏它,请使用new
关键字
但是,如果要调用它,请使用virtual
和override
,或者只是更改方法名称以免隐藏它
class A
{
public virtual void SomeMethod()
{
Console.Write("This is A");
}
}
class B : A
{
public override void SomeMethod()
{
base.SomeMethod();
Console.Write("This is B");
}
public void OtherMethod()
{
Console.Write("This is New method");
}
}
virtual关键字用于修改方法,属性,索引器或 事件声明,并允许其在派生中被覆盖 类。例如,该方法可以被任何 继承它:
需要override修饰符来扩展或修改摘要或 继承的方法,属性,索引器或 事件。
Polymorphism (C# Programming Guide)
在这种情况下的堆中创建对象实例时,键入 对象指针指向A还是B?
您不必担心堆上会发生什么(这些是实现细节),而不必担心语言允许您做什么。
但是,从技术上讲,A不存在,只有B的实例具有A的所有实现(如果需要)
答案 1 :(得分:0)
您必须指定要覆盖虚拟功能。 试试这个:
class A
{
public virtual void SomeMethod()
{
Console.Write("This is A");
}
}
class B : A
{
public override void SomeMethod()
{
Console.Write("This is B");
}
public void OtherMethod()
{
Console.Write("This is New method");
}
}
答案 2 :(得分:0)
要访问当前失败的OtherMethod,您需要告诉A
像B
一样行事。
更改
a.OtherMethod();
到
(a as B).OtherMethod();