zoukankan      html  css  js  c++  java
  • java面向对象--对象初始化

    重载(Overload)是指在一个类里面,多个方法的名字相同,而参数列表(参数的类型、个数和顺序)不同。返回值类型和修饰符与重载无关。解决相同意义的行为使用不同名字的问题。
    构造器最大的作用就是在创建对象时执行初始化。
    默认构造器又名无参构造器,作用是创建一个默认对象。如果类中没有任何构造器,则编译器会自动创建一个默认构造器。如果已经自行定义了任意一个构造器,编译器就不会自动创建无参构造器。

    所有实例共用一份方法,编译器会把当前对象的引用作为第一个参数传入方法内部,以区分不同的调用对象。
    this:在方法内部使用,this表示对“调用方法的那个对象”的引用。最大的作用就是让类中的一个方法,访问该类的另一个方法或属性。
    static方法是没有this的方法,所以静态成员不能访问非静态成员。
    static关键字:修饰的成员表明它是属于类共有的,既可以通过类访问,也可以通过实例访问。
    在方法内部访问同一个类的成员,不需要使用this。
    如果参数变量和成员变量同名时,可以用this.field=field加以区分。
    在构造器中调用构造器:this可以指代重载的其他构造器方法以减少代码重复。注意此时this(arg)必须作为构造器中的第一句代码。

    public class Teacher {
        private String name; 
        private int age;
        public Teacher(String name,int age ){
           this(name);
           this.age=age;
        }
        public Teacher(String name){
            this.name = name;
        }
    }

    静态数据、成员变量及构造器的初始化顺序
    无继承时:
    假设有个名为Dog的类,创建过程如下:
    1.当首次创建类型为Dog的对象时(构造器可以看成静态方法),或者Dog类的静态方法/静态域首次被访问时,Java解释器必须查找类路径,以定位Dog类的编译代码(在Dog.class文件中)。
    2.然后载入Dog.class(这将创建一个Class对象),执行有关静态初始化的动作。因此,静态初始化只在Class对象首次加载的时候进行一次。 静态变量和静态初始块化块按定义的顺序进行初始化。
    3.当用new Dog()创建对象的时候,首先将在堆上为Dog对象分配足够的存储空间。
    4.这块存储空间会被清零,这就自动地将Dog中的所有基本类型数据设置成了默认值(对数字来说就是0,对布尔型和字符型也相同),而引用则被置成了null。 (默认初始化)
    5.执行所有出现于成员变量定义处的初始化动作。(按定义的先后顺序进行显示初始化,包括成员变量和初始化块
    6.执行构造器。
    7.对象构造完毕,将地址赋给引用类型变量。

    有继承时:
    假设有个名为Golden的类,继承自Dog,Dog又继承自Animal,初始化过程如下:
    1.当首次创建类型为Golden的对象时,Java加载器查找Golden类的编译代码(在Golden.class文件中)。
    2.Java加载器会加载Golden.class文件,同时根据Golden.class(extends关键字)加载其基类Dog.class文件,再根据Dog.class加载根基类Animal.class文件。然后从根基类Animal到基类Dog再到子类Golden依次执行静态数据的初始化。 (子类的静态数据在父类的成员变量之前初始化)
    3.当你用new Golden ()创建对象的时候,首先将在堆上为Golden对象(包括本类Golden、基类Dog和根基类Animal中的所有成员变量)分配足够的存储空间。由于子类的构造器不能访问父类的private成员,所以必须利用super关键字来初始化这部分成员变量。
    4.这块存储空间会被初始化默认值即二进制的零。Golden中的所有基本类型数据(包括其基类Dog和Animal中的)设置成了默认值(对数字来说就是0,对布尔型和字符型也相同),而引用(包括其基类Dog和Animal中的)则被置成了null。也就是说在执行任何初始化代码之前,所有实例变量都已设置完默认的初值。
    5.执行根基类Animal中所有成员变量的初始化动作。
    6.执行基根类Animal构造器。
    7.执行基类Dog中所有成员变量的初始化动作。
    8.执行基类Dog构造器。
    9.执行导出类Golden中所有成员变量的初始化动作。
    10.执行导出类Golden构造器。
    简单来说,就是从子类到基类依次加载类的class文件,然后从根基类到子类依次进行静态数据的初始化。再为对象分配存储空间,在存储空间清零后,依次从父类到子类进行实例初始化(包括成员变量初始化,调用构造器2步)。

    Java在开发者没有定义别的super语句时会自动在子类的构造器中插入对父类构造器的调用,该调用并不是简单地执行父类构造函数,具体顺序如下(省略类初始化过程):
    1、进入当前类的构造方法,调用super()(会被编译器改名为<init>,不执行别的代码)直接进入父类构造方法,并递归到java.lang.Object类构造方法。
    2、执行java.lang.Object类的初始化,顺序为先初始化成员变量/初始化块(按照定义顺序),再调用构造方法(super部分不再执行)进行初始化。
    3、运用步骤2的方法初始化java.lang.Object类的直接子类,并递归这个过程到当前类。

     

    注意:
    对象只能通过new constructor()的方式创建,所以编译器在程序员没有编写构造器时会提供默认的无参构造器。Constructors are meant for initializing the members of objects.
    类的加载发生在:new 对象时,访问类的静态数据时,main方法所在的类在运行java应用时。而在类被加载时就会初始化静态数据。
    对象会取得所有实例变量所需的空间,包括一路继承下来的东西。
    在创建对象时,所有父类的构造函数都会被执行:构造函数在执行的过程中,第一件事是调用它父类的构造函数(编译器通过super调用或开发者自己调用有参数的父类构造函数),直到连锁反应到Object这个类为止,即“构造函数链”。
    创建对象过程中,子类对象可能访问从父类继承下来的数据,所以super()必须是构造函数的第一个语句,父类构造函数必须在子类构造函数之前结束。
    this(..)指代当前类的其他构造函数,也必须是构造函数中的第一句语句,所以super()和this()只能二选一。
    每个对象除了保存类的实例变量之外,还保存着实际类信息的引用,存放类信息的内存区,在Java中称为方法区。
    虚方法表,就是在类加载的时候,为每个类创建一个表,这个表包括该类的对象所有动态绑定的方法及其地址,包括父类的方法,但一个方法只有一条记录,子类重写了父类方法后只会保留子类的。

    class Glyph {
        void draw() {
            System.out.println("Glyph.draw()");
        };
        Glyph() {
            System.out.println("Glyph() before draw()");
            draw(); // 调用重写了的子类型方法
            System.out.println("Glyph() after draw()");
        }
    }
    
    class RoundGlyph extends Glyph {
        private int radius = 1;
        RoundGlyph(int r) {
            radius = r;
            System.out.println("RoundGlyph.RoundGlyph(), radius = " + radius);
        }
        void draw() {
            System.out.println("RoundGlyph.draw(), radius = " + radius);
        }
    }
    
    public class PolyConstructors {
        public static void main(String[] args) {
            new RoundGlyph(5);
        }
    }
    /*
    Glyph() before draw()
    RoundGlyph.draw(), radius = 0
    Glyph() after draw()
    RoundGlyph.RoundGlyph(), radius = 5
    */
  • 相关阅读:
    Java实现 蓝桥杯VIP 算法训练 黑色星期五
    Java实现 蓝桥杯VIP 算法训练 比赛安排
    Java实现 蓝桥杯VIP 算法训练 比赛安排
    Java实现 蓝桥杯VIP 算法训练 斜率计算
    Java实现 蓝桥杯VIP 算法训练 斜率计算
    Java实现 蓝桥杯VIP 算法训练 整数平均值
    Java实现 蓝桥杯VIP 算法训练 整数平均值
    控件动态产生器(使用RegisterClasses提前进行注册)
    Delphi编写自定义控件以及接口的使用(做了一个TpgDbEdit)
    Log4delphi使用心得
  • 原文地址:https://www.cnblogs.com/kevin2chen/p/6686927.html
Copyright © 2011-2022 走看看