2021年07月16日 面向对象作业题

案例4-1 类的继承

一、案例描述

1、考核知识点
编号:00104001
名称:类的继承

2、练习目标

  • 了解类继承的意义和作用
  • 掌握如何实现类的继承

3、需求分析

在程序中,继承描述的是事物之间的所属关系,通过继承可以使多种事物之间形成一种关系体系。
为了让初学者熟悉类的继承,本案例将**演示类的继承并编写测试类==验证子类是否拥有父类的可继承成员==**。

4、设计思路(实现原理)
1)设计两个类Student和Teacher
2)抽取两个类共同的内容(如:吃饭、睡觉)封装到一个类Person中,各自特有的部分保留在各自类中。
3)让学生类继承Person类,老师类也继承Person。
4)编写测试类Example01,测试Student类和Teacher是否继承了Person类的成员。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public class HW_01 {

public static void main(String[] args) {
Student student = new Student();
student.eat();
student.sleep();
Teacher teacher = new Teacher();
teacher.eat();
teacher.sleep();
}
}

class Student extends Person {
}

class Teacher extends Person {
}

class Person {
public void eat() {
System.out.println("eat...");
}
public void sleep() {
System.out.println("sleep...");
}
}

运行结果

1
2
3
4
eat...
sleep...
eat...
sleep...

案例4-2 方法的重写

一、案例描述

1、考核知识点
编号:00104002
名称:方法的重写

2、练习目标

  • 了解方法重写的意义和作用
  • 掌握如何进行方法重写

3、需求分析

在继承关系中,子类会自动继承父类中定义的方法,但有时在子类中需要对继承的方法进行一些修改,即对父类的方法进行重写。为了让初学者掌握方法的重写,本案例将编写一个类NewPhone,该类继承Phone类并对Phone类的call()方法进行重写。

4、设计思路(实现原理)

1)定义一个类Phone,编写方法call(),表示打电话功能
2)定义一个Phone的子类NewPhone,重写父类call()方法,让它除了打电话功能外还具有开启语言和关闭语言功能。
3)编写一个测试类Example02,分别调用重写前和重写后的call()方法

二、案例实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public class HW_02_Phone {
public static void main(String[] args) {

Phone phone = new Phone();
phone.call();
System.out.println();
phone = new NewPhone();
phone.call();

}
}

class Phone {
/**
* 打电话的方法
*/
public void call() {
System.out.println("Phone 打电话...");
}
}

class NewPhone extends Phone {
@Override
public void call() {
System.out.println("NewPhone 打电话...");
System.out.println("NewPhone 开启语言...");
System.out.println("NewPhone 关闭语言...");
}
}

三、案例总结

1、子类中需要对继承自父类的方法进行一些修改,这时就用到方法重写。

2、在子类中重写的方法需要和父类被重写的方法具有相同的方法名、参数列表以及返回值类型

3、子类重写的方法的访问修饰权限不能小于父类的

4、重写的主要优点是能够定义子类特有的特征。

案例4-3 super访问父类成员变量

一、案例描述

1、考核知识点

编号:00104003
名称:super关键字

2、练习目标

掌握使用super关键字访问父类成员变量

3、需求分析

子类可以继承父类的非私有成员变量,如果在子类中修改了继承自父类的成员变量的值,再想要访问父类的该成员变量时,可以通过super.成员变量来实现。为了让初学者熟悉super关键字的用法,本案例将分别设计Fu类及其子类Zi,并在Zi类的方法中使用super关键字访问Fu类的成员变量。

4、设计思路(实现原理)

  • 1)编写一个Fu类,在类中定义无参构造和一个初始值为20的num成员变量。
  • 2)Zi类继承Fu类,在子类中对num值进行了修改,同时在子类中定义无参构造和一个无返回值的method()方法,method()方法中使用super关键字调用了Fu类的num成员变量。
  • 3)定义测试类Example03。

二、案例实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public class HW_03_Fu {
public static void main(String[] args) {
Fu fu = new Fu();
System.out.println(fu.num);
Zi zi = new Zi();
System.out.println(zi.num);
zi.method();
}
}

class Fu {
public int num = 20;

public Fu() {
super();
}
}

class Zi extends Fu {
public int num = 30;

public Zi() {
super();
}

public void method() {
System.out.println(super.num);
}
}

三、案例总结

1、使用super关键字调用父类的成员方法。具体格式如下:

1
super.成员方法([参数1,参数2…])

2、被调用的父类成员变量,必须是非private的。

案例4-5 super访问父类构造方法

一、案例描述

1、考核知识点

编号:00104003
名称:super关键字

2、练习目标

掌握如何在子类构造方法中使用super关键字访问父类构造方法

3、需求分析

在子类的构造方法中一定会调用父类的某个构造方法,如果想指定调用类父类中的哪个构造方法,可以使用super关键字来实现。为了让初学者掌握super关键字的用法,本案例将分别设计Fu类及其子类Zi,在Zi类的构造方法中使用super关键字访问Fu类的构造方法。

4、设计思路(实现原理)

  • 1)编写一个Fu类,在类中定义无参构造
  • 2)Zi类继承Fu类,子类中也定义无参构造方法,在构造方法中使用super关键字调用Fu类的构造方法。
  • 3)定义测试类Example05。

二、案例实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class HW_04_Fu {
public static void main(String[] args) {
Fu1 fu1=new Fu1();
System.out.println();
Zi1 zi1=new Zi1();
}

}
class Fu1 {

public Fu1() {
super();
System.out.println("Fu1....");
}

}
class Zi1 extends Fu1 {

public Zi1() {
super();
System.out.println("Zi1....");
}
}

三、案例总结

1、通过super调用父类构造方法的代码必须位于子类构造方法的第一行,并且只能出现一次。

2、在子类的构造方法中通过super指定调用父类的哪个构造方法,如果没有指定,在实例化子类对象时,会自动调用父类无参的构造方法。

3、被调用的父类构造方法,必须是非private的。

案例4-6 final修饰类

一、案例描述

1、考核知识点

编号:00104004
名称:final关键字

2、练习目标

了解final关键字修饰类的特点
掌握final关键字修饰类的用法

3、需求分析

Java中的类被final关键字修饰后,该类将不可以被继承,也就是不能够派生子类。为了让初学者熟悉final关键字修饰类的用法,本案例将分别设计两个类,一个是使用final关键字修饰的Fu类,另一个是继承Fu类的Zi类,验证final关键字修饰的类是否能被继承。

4、设计思路(实现原理)

  • 1)编写一个final关键字修饰的Fu类,类体可以为空
  • 2)编写Zi类,Zi类继承于Fu类,类体可以为空
  • 3)定义测试类Example06。

二、案例实现

1
2
3
4
5
6
7
8
9
10
public class HW_06_FinalTest {
public static void main(String[] args) {
Fu_2 fu_2 = new Fu_2();
Zi_2 zi_2 = new Zi_2();
}
}
final class Fu_2 {
}
class Zi_2 extends Fu_2 {
}

第9行报错:

1
The type Zi_2 cannot subclass the final class Fu_2

运行报错:

1
2
Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
The type Zi_2 cannot subclass the final class Fu_2

三、案例总结

在Java中,被final关键字修饰的类为最终类,不能被其它类继承。

案例4-7 final修饰方法

一、案例描述

1、考核知识点

编号:00104004
名称:final关键字

2、练习目标

掌握使用final关键字修饰方法

3、需求分析

子类可以继承父类的成员方法,并在必要时对方法进行重写,增加了方法的扩展的同时也打破了方法的封装,如果我们希望父类中的某些方法不能被重写,这时就可以使用final关键字来修饰
为了让初学者掌握使用final关键字修饰方法,本案例将分别设计两个类,一个是Fu类,其中定义了final修饰的show()方法,另一个是继承Fu类的Zi类,在Zi类中对show()方法进行重写。

4、设计思路(实现原理)

  • 1)编写一个Fu类,类中定义final修饰的show()方法。
  • 2)编写Zi类,Zi类继承于Fu类,在Zi类中对show()方法进行重写
  • 3)定义测试类Example07,创建Zi类对象,并调用Zi类show()方法。

二、案例实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class HW_07_FinalMethod {
public static void main(String[] args) {
new Fu_7().show();
new Zi_7().show();
}
}
class Fu_7 {
public final void show() {
System.out.println(Fu_7.class.getTypeName() + ".show...");
}
}
class Zi_7 extends Fu_7 {
public void show() {
System.out.println(Zi_7.class.getTypeName() + ".show...");
}
}

第13行报错:

1
2
3
Multiple markers at this line
- Cannot override the final method from Fu_7
- overrides time20210716.homework.Fu_7.show

运行结果:

1
2
3
time20210716.homework.Fu_7show...
Exception in thread "main" java.lang.VerifyError: class time20210716.homework.Zi_7 overrides final method show.()V
at java.lang.ClassLoader.defineClass1(Native Method)

三、案例总结

当一个类的方法被final关键字修饰后,这个类的子类将不能重写该方法。

案例4-8 final修饰局部变量

一、案例描述

1、考核知识点

编号:00104004
名称:final关键字

2、练习目标

掌握使用final关键字修饰局部变量

3、需求分析

Java中被==final修饰的变量为常量,它只能被赋值一次==,也就是说final修饰的变量一旦被赋值,其值不能改变。为了让初学者掌握使用final关键字修饰局部变量,本案例将在类的方法中定义一个final修饰的局部变量,并试着对该变量重新赋值。

4、设计思路(实现原理)

  • 1)编写一个Example08类,类中定义类一个final修饰的局部变量age,为其赋初始值为18。
  • 2)为age重新赋值为20。

二、案例实现

1
2
3
4
5
final int age=18;
age=20;
final int num;
num=12;
num=18;

第2行报错:

1
The final local variable age cannot be assigned. It must be blank and not using a compound assignment

最后一行报错:

1
The final local variable num may already have been assigned

三、案例总结

final修饰的变量表示常量,一经赋值就不能重新赋值。

案例4-9 final修饰成员变量

一、案例描述

1、考核知识点

编号:00104004
名称:final关键字

2、练习目标

掌握使用final关键字修饰成员变量

3、需求分析

在Java中,final修饰的变量表示常量,一经赋值就不能重新赋值。为了让初学者熟悉final修饰变量的情况,本案例将使用final关键字修饰成员变量,观察其是否能够再次赋值。

4、设计思路(实现原理)

  • 1)编写一个Fu类,父类中定义一个变量X,并用final关键字修饰变量。
  • 2)编写Zi类,Zi类继承于Fu类,在子类中对常量再赋新值。
  • 3)定义测试类Example09,观察运行结果。

二、案例实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class HW_09_FinalField {
public static void main(String[] args) {
// new Fu_9();
new Zi_09();
}
}
class Fu_9 {
public final int X;
public final int Y = 20;
{
Y = 30;
}
public Fu_9() {
X = 10;
}
}
class Zi_09 extends Fu_9 {
public Zi_09() {
X = 50;
}
}

编译器报错

第11行:

1
The final field Fu_9.Y cannot be assigned

第19行报错

1
The final field Fu_9.X cannot be assigned

运行结果:

1
2
3
4
5
Exception in thread "main" java.lang.Error: Unresolved compilation problems: 
The final field Fu_9.Y cannot be assigned
The final field Fu_9.X cannot be assigned
at time20210716.homework.Zi_09.<init>(HW_09_FinalField.java:13)
at time20210716.homework.HW_09_FinalField.main(HW_09_FinalField.java:6)

三、案例总结

在本案例中Zi类中对变量X再次赋值,运行结果报错。这是因为Java中被final修饰的变量为常量,它只能被赋值一次,也就是说final修饰的变量一旦被赋值,其值不能改变。如果再次对该变量进行赋值,则程序会在编译时报错