关于多态的困惑!!

来源:百度知道 编辑:UC知道 时间:2024/06/28 05:40:44
例如程序:
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();

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. 任何一个子类的构造函数被调用时都相当于先调用了父类的构造函数然后再运行自己的构造函数,上面已经说过了的:)

流程已经描述的很清楚了,构造函数调用时顺序执行了从父类到子类的所有同参(或指定重写)构造函数;普通方法调用时执行被重写覆盖过后的子类的方法逻辑,如果没有覆盖则执行父类的。