1

首先,我将使用virtualoverride

例如,基类 A 具有方法A.do(),继承的类 B 具有B.do()覆盖 A 的方法。

如果我打电话(B as A).do(),它do()会执行哪个?

或者,如果有一个方法void mymethod(A a) {a.do()},现在我调用它B b; mymethod(b),它会执行b.do()吗?

4

4 回答 4

3

总是会调用最顶层的覆盖方法,即b.Do()or(b as A).Do()((A)b).Do()将调用B.Do().

如果子类覆盖它,我不知道如何从子类调用基方法。

于 2011-09-18T10:43:29.717 回答
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
于 2011-09-18T10:45:20.913 回答
1

这完全取决于 do() 方法是否被声明为虚拟的。如果它不是虚拟的,则调用 A.do()。如果它是虚拟的,则调用 B.do()。它是启用多态性并允许调用独立于引用类型的方法的virtual关键字。

C# 中没有允许从 B 对象引用直接调用虚拟 A.do() 方法的机制。唯一的例外是在 B 类的实例方法中使用 base.do()。

于 2011-09-18T10:53:40.707 回答
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 控制台应用程序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两次。

于 2011-09-18T10:56:31.050 回答