子类&父类实例化顺序优先级分析

先看个例子:

internal class Parent
{
    int x = 1;
    private readonly int y;

    public Parent()
    {
        // 位置1
        this.y = -2;
        PrintFields();
    }

    public Parent(int y) : this()
    {
        // 位置2
        this.y = y;
    }

    public virtual void PrintFields()
    {
        Console.WriteLine("Parent:x={0},y={1}", x, y);
    }
}

internal class SonTom : Parent
{
    int x = 3;
    private int y;

    public SonTom()
    {
        // 位置3
        y = -3;
    }

    public override void PrintFields()
    {
        Console.WriteLine("SonTom: x={0},y={1}", x, y);
    }
}

internal class SonJerry : Parent
{
    int x = 2;
    private int y;

    public SonJerry()
    {
        // 位置4
        y = -3;
        PrintFields();
    }
    
    public new void PrintFields()
    {
        Console.WriteLine("SonJerry: x={0},y={1}", x, y);
    }
}

 

调用并运行:

var parent = new Parent(22);  
// Parent:x=1,y=-2   
原因解释:
初始化时先执行this()方法,此时的y=-2;
然后才执行Parent(int y),此时的y=22,但是已经不输出了



var d = new SonTom(); 
// SonTom: x=3,y=0     
原因解释: 
SonTom子类私有字段先初始化x=3,y=0; 
Parent私有字段初始化 x=1,y=0;  
Parent构造函数执行 x=1,y=-2;  
调用PrintFields(),因为方法被重写(override)了,所以调用的是子类的PrintFields(),此时x=3,y=0;
最后调用子类的构造函数 x=3,y=-3



Console.WriteLine(); 
Parent bc = new SonJerry(); 
// x=1,y=-2 
// x=2,y=-3
原因解释: 
SonJerry子类私有字段先初始化x=2,y=0; 
Parent私有字段初始化 x=1,y=0;  
Parent构造函数执行 x=1,y=-2;  
调用PrintFields(), 因为方法被子类覆盖(new)了,所以父类构造函数中调用的是父类自己的PrintFields()输出x=1,y=-2;  
最后调用子类的构造函数 x=2,y=-3, 因为用new覆盖了, 且Parent.x是私有的, 调用子类的PrintFields()时输出子类自己的 x=2,y=-3


子类的私有变量不会被父类的私有变量覆盖

 

先解释下 readonly( 简单来说,在此例中只可以在构造函数中多次修改值)

在字段声明中,readonly 指示只能在声明期间或在同一个类的构造函数中向字段赋值。 可以在字段声明和构造函数中多次分配和重新分配只读字段。
构造函数退出后,不能分配 readonly 字段。 此规则对于值类型和引用类型具有不同的含义:
1)由于值类型直接包含数据,因此属于 readonly 值类型的字段不可变。
2)由于引用类型包含对其数据的引用,因此属于 readonly 引用类型的字段必须始终引用同一对象。 该对象是可变的。 readonly 修饰符可防止字段替换为引用类型的其他实例。 但是,修饰符不会阻止通过只读字段修改字段的实例数据。

 

由此推出顺序为:

1)子类静态成员变量初始化 
2)子类实例变量初始化 
3)父类静态静态成员变量初始化 
4)父类实例变量初始化 
5)父类构造方法调用 
6)子类构造方法调用。 

posted @ 2021-03-01 18:20  tomkluas  阅读(401)  评论(1编辑  收藏  举报