首先,我将使用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()
吗?
首先,我将使用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()
吗?
总是会调用最顶层的覆盖方法,即b.Do()
or(b as A).Do()
或((A)b).Do()
将调用B.Do()
.
如果子类覆盖它,我不知道如何从子类调用基方法。
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
这完全取决于 do() 方法是否被声明为虚拟的。如果它不是虚拟的,则调用 A.do()。如果它是虚拟的,则调用 B.do()。它是启用多态性并允许调用独立于引用类型的方法的virtual关键字。
C# 中没有允许从 B 对象引用直接调用虚拟 A.do() 方法的机制。唯一的例外是在 B 类的实例方法中使用 base.do()。
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 控制台应用程序5
那是因为您没有覆盖任何东西,而只是将方法隐藏在 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两次。