JAVA 面向对象 | 继承与多态 简单理解和实例

程序需求

1.编写一个 Cat 类,实现 1 个 shout()方法,该方法可以输出小猫的叫声“喵”

2.修改以上程序,为 Cat 类声明一个字段 name 和一个有参的构造函数,以便在实例化对象时,可以设置对象的名字;并使 shout()方法可以根据 name 的值输出对象的名字,如“我的名字叫…,喵”,同时实现默认构造函数。

3.修改以上程序, 自行设计一个有参构造函数并调用。

1
2
3
4
5
6
7
8
9
10
11
12
13
class Cat {
private final String name;

public Cat(String name) {
this.name = name;
cnt++;
}

public void shout() {
System.out.println("My name is" + name + " Meow Meow Meow");
}

}

4.修改以上程序,利用私有字段和 get/set 方法实现能够控制猫的叫声的功能,让它叫几声,它就叫几声,并且能够输出叫声,但是最多叫 10 声。

5.修改以上程序,设计一个静态变量和静态方法统计并显示生成的实例个数。

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
class Cat {
static int cnt=0;
private int n;
private final String name;

public Cat(String name) {
this.name = name;
cnt++;
}
public void shout() {//猫叫方法
System.out.println("My name is" + name);
for (int i = 0; i < Math.min(n,10); i++) {

System.out.print("Meow ");
}
}

public void setN(int n) {//设置猫的叫声数量
this.n = n;
}

public int getCnt() {//返回实例个数
return cnt;
}
}

6.在上一堂课实现的程序基础上,仿照 Cat 类增加一个 Dog 类,也有 shout()方法,能够输出“我的名字叫…. 汪!汪!”等功能。

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
class Dog {
static int cnt=0;
private int n;
private final String name;

public Dog(String name) {
this.name = name;
cnt++;
}

public void shout() {//狗叫方法
System.out.println("My name is" + name);
for (int i = 0; i < Math.min(n,10); i++) {

System.out.print("Woof ");
}
}

public void setN(int n) {//设置狗的叫声数量
this.n = n;
}

public int getCnt() {//返回实例个数
return cnt;
}
}

7.分析 Cat 和 Dog 类的程序,可以发现它们有非常相似的代码。请建立一个父类 Animal 类,把Cat 和 Dog 相同的代码尽量放到 Animal 类中。

8.分析以上程序,可以发现 Cat 和 Dog 类都有 shout()方法,只是叫的声音不同。请修改上述程序,为 Animal 类建立一个 shout()方法,然后让 Cat 和 Dog 去重写这个 shout()方法,实现多态。

9.在以上程序的基础上,增加牛和羊两种动物,而且都要叫出自己的声音。

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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
class Animal {
static int cnt = 0;
public int n;
public final String name;

public Animal(String name) {
this.name = name;
cnt++;
}
public void shout(){

}

public void setN(int n) {//设置狗的叫声数量
this.n = n;
}

public int getCnt() {//返回实例个数
return cnt;
}
}

class Cat extends Animal {
public Cat(String name) {
super(name);
}

public void shout() {
System.out.println("My name is" + name);
for (int i = 0; i < Math.min(n, 10); i++) {

System.out.print("Meow ");
}
}
}

class Dog extends Animal {
public Dog(String name) {
super(name);
}

public void shout() {
System.out.println("My name is" + name);
for (int i = 0; i < Math.min(n, 10); i++) {

System.out.print("Woof ");
}
}
}

class Cow extends Animal {
public Cow(String name) {
super(name);
}

public void shout() {
System.out.println("My name is" + name);
for (int i = 0; i < Math.min(n, 10); i++) {

System.out.print("Mou ");
}
}
}

class Goat extends Animal {
public Goat(String name) {
super(name);
}

public void shout() {
System.out.println("My name is" + name);
for (int i = 0; i < Math.min(n, 10); i++) {

System.out.print("Mie");
}
}
}

10.分析以上程序,可以发现四种动物的 shout()方法中,除了动物叫的声音不同外,几乎是相同的。请把该方法在 Animal 类中实现,但是由于各种动物的叫声不同,需要增加一个方法 getSound(),在子类中获得各种动物的叫声。经过重构,所有的重复都放到父类中,子类变得非常简洁,而且容易修改。

11.由于 Animal 类根本不可能实例化也不需要实例化,所以可以把实例化没有任何意义的父类改成抽象类。请在以上程序的基础上,将 Animal 类改为抽象类,同时 getSound()也应改为抽象方法。

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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
abstract class Animal {
static int cnt = 0;
public int n;
public final String name;
public String Sound;

public Animal(String name) {
this.name = name;
cnt++;
}
public void shout(){
for (int i = 0; i < Math.min(n, 10); i++) {

System.out.print(Sound+' ');
}
}
abstract public void getSound();

public void setN(int n) {//设置动物的叫声数量
this.n = n;
}
public int getCnt() {//返回实例个数
return cnt;
}
}

class Cat extends Animal {
public Cat(String name) {
super(name);
}
public void getSound(){
Sound="Meow";
}

}

class Dog extends Animal {
public Dog(String name) {
super(name);
}
public void getSound(){
Sound="Woof";
}

}

class Cow extends Animal {
public Cow(String name) {
super(name);
}
public void getSound(){
Sound="Mou";
}

}

class Goat extends Animal {
public Goat(String name) {
super(name);
}
public void getSound(){
Sound="Mie";
}
}

11.在四种动物中,Cat 和 Dog 能捉老鼠,请将这个功能设计成接口,并分别由 Cat 和 Dog 两种动物继承实现。

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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
interface CatchMouse{
public void Catch();
}

abstract class Animal{
static int cnt = 0;
public int n;
public final String name;
public String Sound;

public Animal(String name) {
this.name = name;
cnt++;
}
public void shout(){
for (int i = 0; i < Math.min(n, 10); i++) {

System.out.print(Sound+' ');
}
}
abstract public void getSound();

public void setN(int n) {//设置狗的叫声数量
this.n = n;
}
public int getCnt() {//返回实例个数
return cnt;
}
}

class Cat extends Animal implements CatchMouse{
public Cat(String name) {
super(name);
}
public void getSound(){
Sound="Meow";
}
public void Catch(){
System.out.println(name+"as a cat caught a mouse");
}

}

class Dog extends Animal implements CatchMouse{
public Dog(String name) {
super(name);
}
public void getSound(){
Sound="Woof";
}
public void Catch(){
System.out.println(name+"as a dog caught a mouse");
}

}

class Cow extends Animal {
public Cow(String name) {
super(name);
}
public void getSound(){
Sound="Mou";
}
}

class Goat extends Animal {
public Goat(String name) {
super(name);
}
public void getSound(){
Sound="Mie";
}
}


UML类图

image-20210906204507440