zoukankan      html  css  js  c++  java
  • 子类&父类实例化顺序优先级分析

    先看个例子:

    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)子类构造方法调用。 

  • 相关阅读:
    NBIbatis 微信框架
    NBIbatis 框架体系说明
    NBIbatis 基础框架
    .NET开发者必备的工具箱
    开源中国上一些有用的开源系统
    TfS+强制删除签出锁定项
    thinkphp支持大小写url地址访问,不产生下划线
    sqlserver 链接 ODBC 访问 MySql
    ibatis + log4net 配置注意事项
    Devexpress GridView内嵌dx:ASPxGridLookup取得控件值乱跳解决方案
  • 原文地址:https://www.cnblogs.com/tomkluas/p/14464677.html
Copyright © 2011-2022 走看看