首先,A a1 = new B();什么意思?其次如下

例如程序:
using System;

class A
{
public A()
{
Console.WriteLine("A 构造函数");
}
public void Greet()
{
Console.WriteLine("A 问候");
}
public void Talk()
{
Console.WriteLine("A 说话");
}
public virtual void Sing()
{
Console.WriteLine(" 唱歌");
}
}

class B:A
{
public B()
{
Console.WriteLine("B 构造函数");
}
public void Talk()
{
Console.WriteLine("B 说话");
}
public override void Sing()
{
Console.WriteLine("B 唱歌");
}
}

public class Test
{
public static void Main()
{
A a1 = new B(); //困惑1
a1.Talk();
a1.Sing(); //困惑2
a1.Greet();

B a2 = new B(); //困惑3
a2.Talk();
a2.Greet();
a2.Sing();
}
}
的输出结果是:
A 构造函数
B 构造函数
A 说话
B 唱歌
A 问候
A 构造函数
B 构造函数
B 说话
A 问候
B 唱歌
*******************************************
困惑1:首先,A a1 = new B();什么意思?
其次,为什么运行到这句的时候,同时输出了“A 构造函数B 构造函数”?也就是说,为什么运行到这句的时候,同时调用了构造函数A和B?
再次,能否写成B a1 = new B();或者A a1 = new A();?
困惑2:a1.Sing();这句之所以输出“B 唱歌”,是否因为a1是属于B类, 所以调用B类中重写后的Sing()方法?
困惑3:按照程序的运行结果来看,运行B a2 = new B();这句时,也输出了“A 构造函数B 构造函数”。这和A a1 = new B();这句输出的结果相同。请问又这是为什么?
要是有好心人,能附个程序的运行流程就好了。谢谢

白猪掌柜的
浏览 146回答 1
1回答

繁华开满天机

1. A a1 = new B();完成了两项工作,构造一个子类,然后把它Cast成父类并赋值给a1 。 任何一个子类的构造函数被调用时都相当于先调用了父类的构造函数然后再运行自己的构造函数,而不是同时调用。子类向父类进行隐式类型转换是可以的,而父类向子类是不可以的。B a1 = new B();或者A a1 = new A();都回生成对应的类型的实例,而不做类型转换,所以自然是可以的:)2. a1.Sing();执行的是a1这个实例的方法,a1的类型是B,即便被隐式转换为了A,但是不能改变它是B的事实,所以调用的逻辑是B定义的覆盖了A的逻辑。3. 任何一个子类的构造函数被调用时都相当于先调用了父类的构造函数然后再运行自己的构造函数,上面已经说过了的:)流程已经描述的很清楚了,构造函数调用时顺序执行了从父类到子类的所有同参(或指定重写)构造函数;普通方法调用时执行被重写覆盖过后的子类的方法逻辑,如果没有覆盖则执行父类的。
打开App,查看更多内容
随时随地看视频慕课网APP