day11作业------------------Java面向对象--JavaObject02-2
作业
1. 将人,学生和老师(老师多了教工编号和讲课的行为)案例用继承实现,
并添加军人类,军人的特殊属性假设有部队编号,军人特有的行为假设有训练。
2.
a. 声明一个Person类,里面定义了三个属性,name、gender、age(姓名、性别、年龄)
通过构造方法进行赋值。有一个display方法,可以展示对应的姓名性别年龄信息
b. 声明一个Student类,继承自Person类,增加一个独特的属性id(学号)
通过构造方法进行赋值,同时有一个方法可以展示姓名性别年龄学号信息
c. 声明一个Teacher类,继承自Person类,增加course属性(教学课程)
通过构造方法进行赋值,有一个方法,可以显示姓名性别年龄教学课程信息
d.编写一个测试类,验证你的代码.(分别创建Student对象,和Teacher对象,
要求利用子类对象的显示初始化,即在子类构造方法中,调用父类构造方法的方式
来初始化子类对象。)
附加题
分别写出如下两个代码中所示代码的输出
代码1:
1 public class Test { 2 3 public static void main(String[] args) { 4 Sub sub = new Sub(); 5 6 } 7 8 } 9 10 class Base{ 11 static { 12 System.out.println("base static"); 13 } 14 { 15 System.out.println("base构造代码块"); 16 } 17 public Base() { 18 System.out.println("base构造函数"); 19 } 20 } 21 class Sub extends Base{ 22 static { 23 System.out.println("sub static"); 24 } 25 { 26 System.out.println("sub构造代码块"); 27 } 28 public Sub() { 29 System.out.println("sub构造函数"); 30 } 31 }
代码2:
1 public class Obj3 extends Obj1{ 2 Obj2 obj2 = new Obj2(); 3 public Obj3() { 4 System.out.println("obj3"); 5 } 6 public static void main(String[] args) { 7 //Obj3 obj3 = new Obj3(); 8 9 } 10 11 } 12 13 class Obj1{ 14 Obj2 obj2 = new Obj2(); 15 public Obj1() { 16 System.out.println("obj1"); 17 } 18 } 19 class Obj2{ 20 public Obj2() { 21 System.out.println("obj2"); 22 } 23 }
参考答案:
1.
1 package com.day011; 2 /* 3 * 1. 将人,学生和老师(老师多了教工编号和讲课的行为)案例用继承实现, 4 并添加军人类,军人的特殊属性假设有部队编号,军人特有的行为假设有训练。 5 */ 6 public class Demo1 { 7 public static void main(String[] args) { 8 //创建子类对象 9 System.out.println("------子类对象的隐式初始化------"); 10 Student stu1 = new Student(1); 11 stu1.name = "学生赵1"; 12 System.out.println(stu1.name+"--"+stu1.sno); 13 14 System.out.println("------子类对象的显式初始化------"); 15 Student stu2 = new Student("学生赵2",2); 16 System.out.println(stu2.name+"--"+stu2.sno); 17 18 System.out.println("-------父类域的隐藏-------"); 19 //调用子类的方法,在子类方法的方法体中,访问同名成员变量 20 Army army = new Army(); 21 army.armyAccess(); 22 //在子类对象上,调用父类方法,在父类方法的方法体中,访问同名成员变量 23 army.teacherAccess(); 24 //在子类中,实现同时访问,父类,子类中的同名成员变量的值 25 army.allAccess(); 26 27 System.out.println("------方法覆盖------"); 28 //在子类方法体中,调用父类、子类一模一样的成员方法 29 army.armyAccess1(); 30 //在父类方法体中,调用父类、子类一模一样的成员方法 31 army.teacherAccess1(); 32 //在子类类体中,同时访问子类和父类中定义的一模一样的方法 33 army.allAccess1(); 34 } 35 } 36 37 class Human{ 38 String name; 39 //无参构造方法 40 public Human() { 41 //System.out.println("父类的无参构造方法执行了"); 42 } 43 //带参构造方法 44 public Human(String name) { 45 this.name = name; 46 } 47 48 } 49 class Student extends Human{ 50 int sno; 51 52 //子类构造方法。初始化问题:要先调用父类构造方法,在子类构造方法 53 // 首先调用父类构造方法,两种方式:1.子类对象的隐式初始化;2.子类对象的显式初始化 54 55 /* 56 * 1.子类对象的隐式初始化 57 * 条件:1.当父类提供了默认构造方法(无参构造方法); 58 * 2.且子类的构造方法中没有显式调用父类的其他构造方法 59 * 3.在执行子类构造方法之前,jvm会自动执行父类的构造方法(无参构造方法) 60 */ 61 public Student(int sno) { 62 //System.out.println("子类的构造方法执行了"); 63 this.sno = sno; 64 } 65 66 //2.子类对象的显示初始化 67 public Student(String name, int sno) { 68 //显示调用父类的1参构造方法,把参数值通过super传递给父类构造方法 69 super(name); 70 this.sno = sno; 71 } 72 73 } 74 class Teacher extends Human{ 75 String num = "老师001";//老师教工编号 76 public void method() { 77 System.out.println("father---teacher teaching"); 78 } 79 public void teacherAccess() { 80 System.out.println(num); 81 } 82 public void teacherAccess1() { 83 this.method(); 84 } 85 } 86 class Army extends Teacher{ 87 String num = "士兵001";//军人部队编号 88 public void method() { 89 System.out.println("son---soldier training"); 90 } 91 public void armyAccess() { 92 System.out.println(num); 93 } 94 //同时访问到,父类,子类中定义的同名成员变量的值 95 public void allAccess() { 96 //利用super,访问父类中,定义的同名成员变量值 97 System.out.println(num + "--" + super.num); 98 } 99 public void armyAccess1() { 100 this.method(); 101 } 102 public void allAccess1() { 103 method(); 104 super.method(); 105 } 106 }
运行结果:
2.
1 package com.day011; 2 /* 3 * 2. 4 a. 声明一个Person类,里面定义了三个属性,name、gender、age(姓名、性别、年龄) 5 通过构造方法进行赋值。有一个display方法,可以展示对应的姓名性别年龄信息 6 7 b. 声明一个Student类,继承自Person类,增加一个独特的属性id(学号) 8 通过构造方法进行赋值,同时有一个方法可以展示姓名性别年龄学号信息 9 10 c. 声明一个Teacher类,继承自Person类,增加course属性(教学课程) 11 通过构造方法进行赋值,有一个方法,可以显示姓名性别年龄教学课程信息 12 13 d.编写一个测试类,验证你的代码.(分别创建Student对象,和Teacher对象, 14 要求利用子类对象的显示初始化,即在子类构造方法中,调用父类构造方法的方式 15 来初始化子类对象。) 16 */ 17 public class Demo2 { 18 19 public static void main(String[] args) { 20 Student1 stu = new Student1(1,"孙悟空","男",18); 21 stu.display(); 22 System.out.println(); 23 Teacher1 tea = new Teacher1("Java","张三","男",26); 24 tea.display(); 25 } 26 27 } 28 class Person{ 29 String name; 30 String gender; 31 int age; 32 public Person(String name, String gender, int age) { 33 this.name = name; 34 this.gender = gender; 35 this.age = age; 36 } 37 public void display() { 38 System.out.println(name + "--" + gender + "--" + age); 39 } 40 } 41 42 class Student1 extends Person{ 43 int sno; 44 public Student1(int sno, String name, String gender, int age) { 45 super(name, gender, age); 46 this.sno = sno; 47 } 48 public void display() { 49 System.out.println("学号:" + sno); 50 super.display(); 51 } 52 public void stuAccess() { 53 this.display(); 54 } 55 } 56 57 class Teacher1 extends Person{ 58 String course; 59 public Teacher1(String course, String name, String gender, int age) { 60 super(name, gender, age); 61 this.course = course; 62 } 63 public void display() { 64 65 super.display(); 66 System.out.println("所教课程:" + course); 67 } 68 }
运行结果:
3.
附加题:
第一幅图片
1. 创建子类对象之前,首先执行类加载过程
先加载父类,于是父类中的静态代码块的代码先执行
2. 父类加载完毕后,开始加载子类,于是子类静态代码块代码后执行
3. 类加载过程完毕后,首先初始化父类对象,所以首先执行父类中的构造代码块,在执行父类中的构造方法
4. 然后在初始化子类成员,执行子类的构造代码块,子类的构造方法
第二幅图片
1. 程序从 Obj3 obj3 = new Obj3();开始执行
因为Obj3有父类Obj1,所以初始化子类对象之前,先初始化父类对象
先执行,执行Obj1类中,成员变量赋值的语句
Obj2 obj2 = new Obj2();
2. 于是创建 Obj2类的对象,执行Obj2类的构造方法
3. 对Obj3的父类(Obj1)对象的初始化还没完,执行完了Obj1类中的Obj2 obj2 = new Obj2()之后,因为Obj3的父类Obj1的构造方法还没执行完,紧接着执行Obj1类的构造方法,到此为止,Obj3的父类对象才初始化完
4. 接近着才轮到Obj3对象初始化,首先先执行Obj3的成员变量的赋值语句
Obj2 obj2 = new Obj2();执行Obj2的构造方法
紧接着,执行Obj3的构造方法,Obj3对象到此才算初始化完毕