所有的拳头,我将使用virtual
和override
例如,基类A有方法A.do()
,继承的类B有B.do()
,它会覆盖A。
如果我致电(B as A).do()
,do()
会执行吗?
或者,如果有方法void mymethod(A a) {a.do()}
,现在我通过B b; mymethod(b)
调用它,它会执行b.do()
吗?
答案 0 :(得分:3)
将始终调用最顶部覆盖方法,即b.Do()
或(b as A).Do()
或((A)b).Do()
将调用B.Do()
。
如果子类重写它,我不知道如何从子类调用基类方法。
答案 1 :(得分:2)
public class A
{
public virtual void Do() { Console.Write("a"); }
public void Do2() { Console.Write("a2"); }
}
public class B : A
{
public override void Do() { Console.Write("b"); }
public new void Do2() { Console.Write("b2"); }
}
class Program
{
static void Main(string[] args)
{
B b = new B();
A a = b;
b.Do(); //b
( b as A ).Do(); //b
a.Do(); //b
( (A)b ).Do(); //b
( b as A ).Do2(); //a2
( (A)b ).Do2(); //a2
( b ).Do2(); //b2
}
}
输出:
b b b b
a2 a2 b2
答案 2 :(得分:1)
这完全取决于do()方法是否被声明为虚拟。如果它不是虚拟的,则调用A.do()。如果它是虚拟的,则调用B.do()。 virtual 关键字支持多态,允许调用独立于引用类型的方法。
C#中没有允许从B对象引用直接调用虚拟A.do()方法的机制。唯一的例外是在类B的实例方法中使用base.do()。
答案 3 :(得分:1)
public class A
{
public A() { }
public void Do() { Console.Write("A"); }
}
public class B : A
{
public B() { }
public void Do() { Console.Write("B"); }
}
class Program
{
static void Main(string[] args)
{
B b = new B();
b.Do(); //<-- outputs B
(b as A).Do(); //<-- outputs A
}
}
编译器警告隐藏 而不是覆盖:
警告1'ConsoleApplication5.B.Do()'隐藏继承的成员 'ConsoleApplication5.A.Do()'。如果隐藏了,请使用new关键字 意。 c:\ Program.cs 18 21 ConsoleApplication5
因为你没有覆盖任何东西,只是将方法隐藏在A。
<强>然而强>
public class A
{
public A() { }
public virtual void Do() { Console.Write("A"); }
}
public class B : A
{
public B() { }
public override void Do() { Console.Write("B"); }
}
在覆盖方法时调用 B 两次。