案例6-10分析
teacher.java源代码
package day701;
public class Teacher extends Person {
String department;// 部门
int schoolAge;// 教龄
public Teacher() {
System.out.println("构造器Teacher()被调用");
}
public Teacher(String name) {
// 调用父类中的构造器Person(String theName)
super(name);
System.out.println("构造器Teacher(String name)被调用");
}
public Teacher(int theSchoolAge) {
this.schoolAge = theSchoolAge;
System.out.println("构造器 Teacher(int theSchoolAge)被调用 schoolAge = " + schoolAge);
}
public Teacher(String dept, int theSchoolAge) {
// 调用本类中重载的构造器Teacher(int theSchoolAge)
this(theSchoolAge);
department = dept;
System.out.println("构造器 Teacher(String dept,int theSchoolAge)被调用 department = " + dept);
}
// 初始化块
{
this.department = "教务部";
System.out.println("Teacher初始化块执行后:name=" + this.name + " ,age=" + this.age + " ,sex=" + this.sex
+ ",department =" + this.department);
}
}
TestInit.java源代码
package day701;
public class TestInit {
public static void main(String[] args) {
System.out.println("------------------------------------");
Person t1 = new Teacher();
System.out.println("");
System.out.println("------------------------------------");
Person t2 = new Teacher("Tom");
System.out.println("");
System.out.println("------------------------------------");
Person t3 = new Teacher("财务部", 20);
}
}
Person.java源代码
package day701;
public class Person {
String name;
int age;
String sex;
public Person() { //
this("zhangsan");
System.out.println("构造器Person()被调用");
sex = "Male";
System.out.println("name=" + name + " ,age=" + age + " ,sex=" + sex);
}
public Person(String theName) {
this("lisa", 20);
System.out.println("构造器Person(String theName)被调用");
this.name = theName;
System.out.println("name=" + name + " ,age=" + age + " ,sex=" + sex);
}
public Person(String theName, int theAge) {
System.out.println("构造器Person(String theName,int theAge)被调用");
this.name = theName;
this.age = theAge;
System.out.println("name=" + name + " ,age=" + age + " ,sex=" + sex);
}
// 初始化块
{
this.name = "Tony Blair";
this.age = 50;
this.sex = "Female";
System.out.println("Person初始化块执行后:name=" + this.name + " ,age=" + this.age + " ,sex=" + this.sex);
}
}
Person t1 = new Teacher()分析
①先将主类的字节码文件加载到方法区的类代码区,找到与主类绑定的主方法;
②创建一个Person类的对象,对象名为t1,此时应该将Person类的字节码文件加载到类代码区;
③从创建对象的语句上看,我们能知道,最后肯定要调用Teacher(子)类的无参构造方法,将Teacher(子)类的无参构造方法压栈,但在这之前我们要看Teacher类中要调用Person(父)类的哪个构造方法,Teacher(子)类构造方法中没有特别强调调用Person(父)类的哪个构造方法,会默认调用Person(父)类的无参构造方法,再Person(父)类的无参构造方法压栈,Person(父)类的无参构造方法里使用this(“zhangsan”),指的是要在调用无参构造方法之前应该先调用有应该参数的构造方法,我们要再将Person(String theName)压栈,这里面有一个theName接收传过来的参数,此时构造方法栈里的Person(String)构造方法里theName的值应为zhangsan;而这个构造方法里第一句是this(“lisa”,20),我们需要在调用这个有参构造方法前调用有两个参数的构造方法Person(String theName,int theAge),再将这个构造方法压栈,上一个构造方法将两个参数的值传给Person(String theName,int theAge)构造方法,此时theName的值为lisa,theAge的值为20;压栈完成
④压栈完成之后,我们开始为对象在堆里开辟一个空间,这里有继承Person类的属性:name、age、sex,这三个元素和Person类是动态绑定的,有初始值,还有新增的department、schoolAge元素,然后再执行最后的初始化块,name的值由null变为了Tony Blair,age的值变成50,sex的值变成了Female,此时再从构造方法栈中弹出对应的构造方法,遵从先进后出的原则,第一个弹出的是Person(String theName,int theAge)构造方法,将值射入元素内,name的值由Tony Blair变成了lisa,age变成了20;
⑤第二次弹出的是Person(String theName)构造方法,将theName的值射入name元素内,name的值变成了zhangsan;
⑥第三次弹出的是Person()构造方法,里面的语句sex =“Male”;修改了sex元素,sex的值变成了Male;
⑦第四次弹出的是Teacher()构造方法,没有改变元素,只是执行了输出语句;
⑧所有构造方法弹出栈完成,最后执行Teacher()类的初始化块,将department的值改为了教务部
Person t3 = new Teacher(“财务部”,20)分析
①从创建对象的语句上看,我们能知道,最后肯定要调用Teacher(子)类的有一个参数的构造方法,将Teacher(子)类的有参构造方法压栈,Teacher(子)类构造方法中强调调用Teacher(子)类的Teacher(String dept,int theSchoolAge)构造方法,将Teacher(String dept,int theSchoolAge)构造方法压栈,这里面有两个形参它们的值应该是接收到传过来的"财务部",20,所有这里面dept的值为"财务部",theSchoolAge的值为20,Teacher(子)类的有两个参构造方法里使用this(theSchoolAge)指的是要在调用这个有两个参构造方法之前应该先调用有本类中有一个参数的构造方法,我们要再Teacher(int theSchoolAge)压栈,这里面有一个theSchoolAge接收传过来的参数,此时构造方法栈里的Teacher(int theSchoolAge)构造方法里theSchoolAge的值应为20;而这个构造方法里第一句没有再强调调用哪个构造方法,默认会调用父类的无参构造方法,将Person类的无参构造方法Person()压栈,Person(父)类的无参构造方法压栈,Person(父)类的无参构造方法里使用this(“zhangsan”),指的是要在调用无参构造方法之前应该先调用有应该参数的构造方法,我们要再将Person(String theName)压栈,这里面有一个theName接收传过来的参数,此时构造方法栈里的Person(String)构造方法里theName的值应为zhangsan;而这个构造方法里第一句是this(“lisa”,20),我们需要在调用这个有参构造方法前调用有两个参数的构造方法Person(String theName,int theAge),再将这个构造方法压栈,上一个构造方法将两个参数的值传给Person(String theName,int theAge)构造方法,此时theName的值为lisa,theAge的值为20;压栈完成
②压栈完成之后,我们开始为对象在堆里开辟一个空间,这里有继承Person类的属性:name、age、sex,这三个元素和Person类是动态绑定的,有初始值,还有新增的department、schoolAge元素,然后再执行最后的初始化块,name的值由null变为了Tony Blair,age的值变成50,sex的值变成了Female,此时再从构造方法栈中弹出对应的构造方法,遵从先进后出的原则,第一个弹出的是Person(String theName,int theAge)构造方法,将值射入元素内,name的值由Tony Blair变成了lisa,age变成了20;
③第二次弹出的是Person(String theName)构造方法,将theName的值射入name元素内,name的值变成了zhangsan;
④第三次弹出的是Person()构造方法,里面的语句sex =“Male”;修改了sex元素,sex的值变成了Male;
然后再执行Teacher()类初始化块的内容,department的值改为教务部
⑤第四次弹出的是Teacher(int theSchoolAge)构造方法,这里把theSchoolAge的值改为了20;
⑥第五次弹出的是Teacher(String dept,int theSchoolAge)构造方法,将department的值改为财务部,theSchoolAge的值改为20;
⑦所有构造方法全部弹出,对象创建完成
总结:
封装类
基本数据类型对应的封装类
简单数据类型 封装类
boolean Boolean
byte Byte
short Short
int Integer
long Long
char Character
float Float
double Double
继承关系
Character、Number、Boolean都继承了Object
Byte、Short、Integer、Long、Float、Double继承了Number
特点
封装类都是final修饰,不能被继承
封装类的属性值不能被改变,它没有set方法
封装类可以和基本类型数据进行混合计算:自动装箱和自动拆箱
创建封装类
例如:Short short = new Short((short)1);
Float d=new Float(“30.5f”);
获取封装类的属性值
xxValue():封装类对象属性的获取(除了Boolean类和Character类)
例如:Integer i1 = new Integer(10); int a=i1.intValue();
toString(): 以字符串形式返回封装类对象表示的基本类型。
封装类和对应基本类型的转换
封装类转换成字符串:String str1=i1.toString();
字符串转换为封装类对象:Integer k3=Integer.valueOf("12");(除去Character和Boolean类型)
字符串转换为基本类型的数据:int n=Integer.parseInt("123");(除去Character和Boolean类型)