【发布时间】:2026-01-07 04:10:02
【问题描述】:
我的烦恼是:在下面显示的代码中,它应该显示A,然后是B。但它显示B 然后B。为什么会这样?
我的感觉是,A 的构造函数在创建B 的对象时首先被执行。在那种情况下,B 中的方法不会被击中吧?所以它应该是A.Display(),结果应该是A。另外,a.Display() 应该返回 B,因为我们有覆盖。
所以我希望A 然后是B。因为它不是重载而是压倒一切。我知道这些东西的定义,我希望了解这种行为的原因以及它在内部是如何工作的,因为我不相信BB 但AB。
代码
class A
{
public A()
{
this.Display();
}
public virtual void Display()
{
Console.WriteLine("A");
}
}
class B :A
{
public override void Display()
{
Console.WriteLine("B");
}
}
class C
{
static void Main()
{
A a = new B();
a.Display();
Console.WriteLine();
Console.ReadLine();
}
}
输出
1) 在派生类中重写 Display 方法会产生以下结果:
A a = new A(); // ---> AA
B a = new B(); // ---> BB // I expect AB.
A a = new B(); // ---> BB // I expect AB.
2) 在派生类的 Display 方法中使用 NEW 关键字会产生以下结果:
B a = new B(); // ---> AB // I Expect AA here.
A a = new B(); // ---> AA
A a = new A(); // ---> AA
3) 更有趣的发现是:
当我在派生构造函数中使用base.Display() 并覆盖派生类中的基方法时,它给了我BAB
至少在这方面我看不到任何逻辑。因为,它应该给BBB
【问题讨论】:
-
当A的构造函数运行时,你实际上在B中。因此,由于
Display被覆盖,this.Display返回B -
@OldProgrammer:一点也不。我不需要定义重载或覆盖。我完全理解这一点。但我不理解这种行为。我期待A。我不期待B。我首先期待A。然后 B.
-
正如@Szymon 在他的回答中解释的那样,当你有一个
B类型的对象时,A中的构造函数会调用Display的B方法。之所以如此,是因为您正在覆盖而不是隐藏基类的方法。因此,在B类型的对象中,A类中的Display方法“不存在”*(因为您确实覆盖了它),如果您隐藏了它,它的行为将与您预期的一样。 *:根据 Zerkey 的回答,您仍然可以通过base.Display获得它。 -
@Theraot:不不不,我对很少的输出感到满意,但对其他一些奇怪的输出不满意。直到现在我以为我知道压倒一切。现在非常好笑。这现在的行为有所不同。请查看我在上面解释的所有场景,并强调了我有顾虑的地方。 (第 1、2、3 点)。
-
我已经对您的问题进行了编辑,我会在答案中查看每个输出。顺便说一句:没有“重载”(至少不像 C# 中所理解的那样),使用关键字“new”不是重载它是隐藏的。