作者:苏格拉没有底YI_670 | 来源:互联网 | 2023-09-18 23:18
using System;
class A
{
public A()
{
PrintFields();
}
public virtual void PrintFields(){}
}
class B:A
{
int x=1;
int y;
public B()
{
y=-1;
}
public override void PrintFields()
{
Console.WriteLine("x={0},y={1}",x,y);
}
当使用new B()创建B的实例时,产生什么输出?
答:X=1,Y=0;x= 1 y = -1
16 个解决方案
x=1,y=-1
当类A在哪里起什么作用呢?
根本就没关系嘛
That is a bad exam question.
1. It is bad to call virtual function in the constructor, because the derived class could be not yet fully initialized.
2. Because the derived class is not yet fully initialzed ( y = -1 is not yet assigned ), calling the virtual function
gives you the 'wrong' answer.
你写个主函数调试一下
x=1,y=0 是因为 New B是 先要用A的构造函数
所以就出现了上面的
x=1,y=-1是因为 用了B的构造函数
看看构造函数就知道了
Correction to my previous post:
...
class B
: A
{
...
是类初始化顺序你没有高明白了
先是基类的构造函数,然后是继承类的构造函数
这里先是a的构造函数,调用PrintFields();,但是a的PrintFields();是虚拟的,什么都没有做,然后调用他的实现方法,就是b 的PrintFields();,显示x,y,这时候x是初始化为1,y没有初始化,默认0,所以显示x=1,y=0。
然后构造b,调用b的构造函数,把y初始化为-1.然后是 obj.PrintFields();这句,调用了b的PrintFields()方法,显示x和y,这是后x没有变,y在b的构造函数中赋值-1
所以显示的时候就是x=1,y=-1
执行结果是 X=1,Y=0;x= 1 y = -1
x=1,y=0
调用顺序
基类(A)构造函数 -> A PrintFields() (由于被Boverride,所以实际是调用B的PrintFields()) -> B构造函数
这段代码的执行顺序如下?
using System;
class A
{
public A()
{
PrintFields(); // 2
}
public virtual void PrintFields(){}
}
class B:A
{
int x=1;
int y;
public B()
{
y=-1; /// 1.
}
public override void PrintFields()
{
Console.WriteLine("x={0},y={1}",x,y); // 3.
}
首先是类B中的变量声明,X = 1,y是随机的,可能是0,也可能是别的,由编译器的不同而不同,
再次是执行B的构造函数,进而在执行A的构造函数,
在执行PrintFields函数,此时由于PrintFields是虚函数,而此时B中正好重载了这个函数,因此执行B找中的PrintFields函数。输出时X = 1,y由于没有初始化,此时不知道是什么值,因该是随机值,视编译器而定!!!C#的编译器应该会初始化为0.
x= 1 y = -1
主要是考你的理论基础和思路。
x=1, y=0
y=-1是在调用base的构造函数之后运行的,之后就不会再调用PrintFields()方法了,所以LZ的答案不对。。。