猫抓老鼠-Java面向对象特点梳理
我们先设计一个猫抓老鼠的小游戏:
⊙猫和老鼠都有名字和体重两种属性,猫有抓老鼠的方法,对应的老鼠则有逃跑的方法。
⊙首先游戏的结果是猫抓住了老鼠或者老鼠逃跑了,对于这两种情况,我们用体重来区分,若猫的体重大于或等于老鼠的体重,则猫可实现抓住老鼠的方法,若猫的体重小于老鼠的体重,则老鼠实现了逃跑的方法。
分析一下,第一步我们需要建立两个类:Cat、Mouse;并且分别声明其各自拥有的方法:
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
|
//Cat.java package Testprogramming //打包语句,将Cat类存于TestProgramming包中随后解释其作用; Public class Cat{ public String name; public int weight; Cat(){ //注意为了不至于在创建Cat类的实例化对象的时候出现错误,我们最好写一个空的构造方法 //若没有它则Cat cat=new Cat();语句会报错!至于猫的属性,可以用相应的get/set方法获得 } Cat(String name, int weight){ this .name=name; this .weight=weight; } //下面补上相应的get/set方法 public String getName(){ return name; } public void setName(String name){ this .name } public int getWeight(){ return weight; } publuc void setWeight( int weight){ this .weight; } //重写Object类的toString方法,以得到猫的信息 public String toString(){ return "Cat [名字=" + name + ", 体重=" + weight + "]" ; } //最后声明猫抓老鼠的方法,因为猫抓住的是老鼠这一类动物,所以返回值类型应该是个Mouse类 public Mouse catchMouse(Mouse mouse){ return mouse } } //Mouse类的构成和Cat类基本相同 //Mouse.java package Testprogramming public class Mouse{ public String name; public int weight; Mouse(){ } Mouse(String name, int weight){ this .name=name; this .weight=weight; } public String getName(){ return name; } public void setName(String name){ this .name } public int getWeight(){ return weight; } publuc void setWeight( int weight){ this .weight; } public String toString(){ return "Mouse [名字=" + name + ", 体重=" + weight + "]" } public Cat escapeCat(Cat cat){ return cat; } //若猫的体重小于老鼠的体重,则老鼠可以实现逃跑的方法 public static void inform( boolean b){ if (b== false ){ System.out.println( "猫抓住了老鼠" ); } else { System.out.println( "猫抓老鼠游戏中,老鼠体重超标,猫输了游戏" ); } } |
下面我们编写测试类,实例化一下Cat和Mouse类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
//Test_Cat_Mouse.java package Testprogramming public class Test_Cat_Mouse{ public static void main(String[] args){ String string1,string2; boolean boolean ; //首先实例化一个Cat、Mouse Cat catTom= new Cat( "Tom" , 50 ); Mouse mouseLisa= new Mouse( "Lisa" , 40 ); if (!((bool=mouseLisa.getWeight()==catTom.getWeight()) &&(bool=mouseLisa.getWeight()<=catTom.getWeight()))){ catTom.catchMouse(mouseLisa); System.out.println( "猫" +catTom+ "抓住了" +mouseLisa+ "老鼠" ); } else { mouseLisa.escapeCat(catTom); System.out.println( "老鼠" +mouseLisa+ "逃脱了" + "猫" +mouseLisa+ "的捕捉" ); } string1=catTom.toString(); string2=mouseLisa.toString(); } } |
以上就是我们猫抓老鼠小游戏的实现,我们由此可以回顾一下,Java面向对象编程的特点有三个,分别是:封装(Eccapsulation)、继承(Inheritance)、多态(Ploymorphism);
封装:类的使用者不需要知道类是如何实现的,而实现的过程经过封装,用户只需知道如何使用
包括两种<1>打包(package PackageName)
<2>访问权限:public/default/protected/private
继承:在已有类的基础上拓展属性和方法的能力用关键字extends实现
多态:不同对象面对同一种行为表现出不同的形式
了解了封装的特点之后,我们可以对前面的例子加以分析,如封装:我们可以将Cat、Mouse类以及测试类存到同一个包里(package TestProgramming),此时default以及protected权限就与最大权限public相当,但对于最小权限private,其修饰的成员只能在本类中被访问。
对于继承,我们先总体的看一下,因为Cat类和Mouse类都拥有相同的属性name和weight,而且猫和老鼠本身就是动物,也就是说他俩都是动物的一种,而且还拥有相同的属性,此时我们即可建立一个动物类Animal,在Animal类中定义Cat类和Mouse类的相同属性name、weight;当Cat和Mouse继承了Animal类时,也就同时拥有了name、weight属性;这是一种改进,同时也是一种优化。代码如下:
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 Animal{ public String name; public int weight; Animal(){ //后面我们会说一下子类中super关键字出现时的几种可能情况 } Animal(String name, int weight){ this .name=name; this .weight=weight; } //写到这里就可以了,因为建立Animal类的目的就是得到它的两个属性; } //下面是修改后的部分Cat类代码,Mouse类与之基本相同,故写Cat一参考 | public class Cat extends Animal{ | public class Cat extends Animal{ Cat(){ | Cat(){ | } | } Cat(String name, int weight){ | Cat(String name, int weight){ super (); //调用父类无参数的构造方法 | super("catTom",50);//调父类有参构造方法 this .name=name; | } this .weight=weight; | } | } | } | //以上两种实现都可以,主要是要区分清楚this与super的使用规范,后面会详细说明 |
在继承这块我们需要注意的无非就是this与super的用法以及方法的重写与重载,java培训这两方面下一篇博文里会详细说明;我们接着看多态这一部分
对于多态:我们仍然在本例说明
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
|
//我们重新写一个测试类 //Test_Cat_Mouse.java package Testprogramming public class Test_Cat_Mouse{ public static void main(String[] args){ String string1,string2,string3,string4; boolean boolean ; //保留此前的实例加以区别 Cat catTom1= new Cat( "Tom" , 50 ); Mouse mouseLisa1= new Mouse( "Lisa" , 40 ); //利用父类句柄,创建子类对象 Animal catTom2= new Cat( "Tom" , 50 ); //向上转型,即子类对象转为父类对象 Animal mouseLisa2= new Mouse( "Lisa" , 40 ); //向上转型,即子类对象转为父类对象 if (!((bool=mouseLisa.getWeight()==catTom.getWeight()) &&(bool=mouseLisa.getWeight()<=catTom.getWeight()))){ catTom1.catchMouse(mouseLisa); System.out.println( "猫" +catTom+ "抓住了" +mouseLisa+ "老鼠" ); } else { mouseLisa1.escapeCat(catTom); System.out.println( "老鼠" +mouseLisa+ "逃脱了" + "猫" +mouseLisa+ "的捕捉" ); } // if (!((bool=mouseLisa.getWeight()<=catTom.getWeight()))){ catTom2.catchMouse(mouseLisa); //报错 System.out.println( "猫" +catTom+ "抓住了" +mouseLisa+ "老鼠" ); } else { mouseLisa2.escapeCat(catTom); //报错 System.out.println( "老鼠" +mouseLisa+ "逃脱了" + "猫" +mouseLisa+ "的捕捉" ); } string1=catTom.toString(); string2=mouseLisa.toString(); string3=catTom.toString() string4=mouseLisa.toString() } } 此时我们会发现,Animal句柄创建的Cat以及Mouse对象无法访问其各自拥有的方法,而原因正是此时这个对象属于父类Animal,而不再是子类Cat以及Mouse创建的了所以无法引用,要解决此类问题,就需要向下转型,即把父类对象转为子类对象;代码如下: Animal animal= new Cat( "catTom" , 50 ); Cat catTom=(Cat)animal; //此时catTom就可以调用Cat类的catchMouse()方法了 |
总结:面向对象的三个特点封装、继承、多态在编程中时刻体现,这是基础也是细节,需要仔细理解这
三者之间的区别与联系。