1 构造方法
1.1 构造方法Constructor概述
创建对象要明确属性值,此时需要用到构造方法,即对象创建时要执行的方法,用来给对象的属性进行初始化。
在new对象时,知道其执行的构造方法是什么,就可以在执行这个方法的时候给对象进行属性赋值。
Perons p = new Person("张三",23); 在new的时候给p对象的name属性和age属性进行赋值,使这个对象的属性有值。
构造方法没有返回值类型,也不需要写返回值。因为它是用来构建对象的,对象创建完方法就执行结束。
格式特点:
a:方法名与类名相同(大小也要与类名一致)
b:没有返回值类型,连void都没有
c:没有具体的返回值return;
每一个class类都必须有一个构造方法,如果不定义空参构造方法,系统会自动生成一个空参构造方法,如果定义了构造方法,无论空参还是有参,系统都不再提供空参构造方法了。
此时如果还想使用无参构造方法,就必须自己给出。建议永远自己给出无参构造方法。
什么时候需要在类中写构造方法?如果对象在创建时就要明确属性值,这时就需要在定义类的时候书写有参构造方法。(不写也有默认的构造方法)。
一个类可以有多个构造方法,多个构造方法是以重载的形式存在的,构造方法可以被private修饰,作用:其他程序无法创建该类的对象。
构造方法举例
class Person { private int age; private String name; // Person的构造方法,拥有参数列表 Person(int a, String nm) { // 接收创建对象时传递进来的值,将值赋给成员属性 age = a; name = nm; } }
1.2 给成员变量赋值的两种方式的区别
setXxx()方法:修改属性值
构造方法:给对象中属性进行初始化
1.3 构造方法的内存加载过程
有一个Person类, 创建Person 对象new Person()
1、首先会将main方法压入栈中,执行main方法中的 new Person(23,"张三");
2、在堆内存中分配一片区域,用来存放创建的Person对象,这片内存区域会有属于自己的内存地址(0x88)。然后给成员变量进行默认初始化(name=null,age=0)。
3、执行构造方法中的代码(age = a ; name = nm;),将变量a对应的23赋值给age,将变量nm对应的”张三赋值给name,这段代码执行结束后,成员变量age和name的值已经改变。执行结束之后构造方法弹栈,Person对象创建完成。将Person对象的内存地址0x88赋值给p2。
1.4 构造方法和一般方法区别
1.格式:构造方法没有返回值和返回值类型
2.作用:构造方法用来给成员变量初始化;
3.调用方式:构造方法创建对象时调用, 或者this() super()语句调用
4.执行时机:构造方法在对象创建时就执行了,且只执行一次。
1.5 this在构造方法之间的调用
构造方法,无法通过构造方法名来相互调用。构造方法之间的调用通过this关键字来完成。
构造方法调用格式:this(参数列表);
this调用构造方法的案例:
class Person { private int age; private String name; // 无参构造方法 Person() { } // 姓名初始化构造方法 Person(String nm) { name = nm; } // 姓名和年龄初始化构造方法 Person(String nm, int a) { // 由于已经存在给姓名进行初始化的构造方法 name = nm;因此只需要调用即可 // 调用其他构造方法,需要通过this关键字来调用 this(nm); // 给年龄初始化 age = a; } }
1.6 构造方法调用的原理
1、先执行main方法,main方法压栈,执行其中的new Person(“张三”,23);
2、堆内存中开辟空间,并为其分配内存地址0x33,,紧接着成员变量默认初始化(name=null age = 0);
3、拥有两个参数的构造方法(Person(String nm , int a))压栈,在这个构造方法中有一个隐式的this,因为构造方法是给对象初始化的,那个对象调用到这个构造方法,this就指向堆中的那个对象。
4、由于Person(String nm , int a)构造方法中使用了this(nm);构造方法Person(String nm)就会压栈,并将“张三”传递给nm。在Person(String nm , int a)构造方法中同样也有隐式的this,this的值同样也为0x33,这时会执行其中name = nm,即把“张三”赋值给成员的name。当赋值结束后Person(String nm , int a)构造方法弹栈。
5、程序继续执行构造方法(Person(String nm , int a)中的age = a;这时会将23赋值给成员属性age。赋值结束构造方法(Person(String nm , int a)弹栈。
6、当构造方法(Person(String nm , int a)弹栈结束后,Person对象在内存中创建完成,并将0x33赋值给main方法中的p引用变量。
调用其他构造方法的语句必须定义在构造方法的第一行,原因是初始化动作要最先执行。
2 this关键字
2.1 this关键字概述
this代表当前对象的引用,用来区别同名的成员变量与局部变量(this.成员变量),谁来调用我,我就代表谁
什么时候使用this呢?
1 当类中成员变量和局部变量同名时,为了区分,需要使用this关键字
2 写功能的时候,可能用到this。比如比较两个对象的年龄compare();equals();
3 构造函数中使用this,this()必须放在第一行。
this什么时候存在的?当创建对象的时候,this存在
2.2 super关键字
代表当前对象父类的引用
2.3 this和super的使用区别
a:调用成员变量
this.成员变量 调用本类的成员变量,也可以调用父类的成员变量
super.成员变量 调用父类的成员变量
b:调用构造方法
this(...) 调用本类的构造方法
super(...) 调用父类的构造方法
c:调用成员方法
this.成员方法 调用本类的成员方法,也可以调用父类的方法
super.成员方法 调用父类的成员方法
2.4 this应用示例
需求:在Person类中定义功能,判断两个人是否是同龄人
class Person { private int age; private String name; public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public void speak() { System.out.println("name=" + this.name + ",age=" + this.age); } // 判断是否为同龄人 public boolean equalsAge(Person p) { // 使用当前调用该equalsAge方法对象的age和传递进来p的age进行比较 // 由于无法确定具体是哪一个对象调用equalsAge方法,这里就可以使用this来代替 return this.age == p.age; } public static void main(String[] args) { Person p1 = new Person(); Person p2 = new Person(); p1.setName("zhangsan"); p1.setAge(13); p2.setName("lisi"); p2.setAge(14); System.out.println("年龄相同?..." + p1.equalsAge(p2)); } }
3 super关键字
3.1 super关键字概述
代表当前对象父类的引用
3.2 子父类中构造方法的调用
子类创建对象、使用子类构造方法时,都会调用父类构造方法,因为子类构造方法第一行都有默认的隐式super();语句。
原因:子类继承了父类内容,子类创建对象时,必须先到父类中去执行父类的初始化动作,这样,才可以使用父类中的内容。
子类默认会调用父类的无参构造,当父类中没有空参构造方法时,子类构造方法调用父类的无参构造会报错,所以子类构造方法必须有显式的super语句,指定要访问的父类有参构造方法。
格式:
调用本类中的构造方法:this(实参列表);
调用父类中的空参构造方法:super();
调用父类中的有参构造方法:super(实参列表);
class Fu{ int num ; Fu(){ System.out.println("Fu构造方法"+num); num = 4; } } class Zi extends Fu{ Zi(){ //super(); 调用父类空参数构造方法 System.out.println("Zi构造方法"+num); } } public class Test { public static void main(String[] args) { new Zi(); } } >>> Fu构造方法0 Zi构造方法4
3.3 创建子类对象过程的细节
1 构造方法第一行,写this()还是super()?
this() 是调用本类的构造方法,super()是调用父类的构造方法, 且两条语句不能同时存在
保证子类的所有构造方法调用到父类的构造方法即可,无论如何,子类的所有构造方法,必须直接或间接调用到父类构造方法;
2 如果子类构造方法第一行写了this调用了本类其他构造方法,那么super调用父类的语句还有吗?
此时是没有的,因为this()或super(),只能定义在构造方法的第一行,因为初始化动作要先执行。
3 父类构造方法中是否有隐式的super呢?父类的父类是谁呢?super调用的到底是谁的构造方法呢?
有。记住:只要是构造方法默认第一行都是super();Java定义了一个所有对象的父类Object