1700454680
例如,可以在AbstractToy中声明将声音、形状都委托给AbstractGun处理,仿真枪嘛,形状和声音都要和真实的枪一样了,然后两个基类下的子类自由延展,互不影响。
1700454681
1700454682
在Java的基础知识中都会讲到继承,Java的三大特征嘛,继承、封装、多态。继承就是告诉你拥有父类的方法和属性,然后你就可以重写父类的方法。按照继承原则,我们上面的玩具枪继承AbstractGun是绝对没有问题的,玩具枪也是枪嘛,但是在具体应用场景中就要考虑下面这个问题了:子类是否能够完整地实现父类的业务,否则就会出现像上面的拿枪杀敌人时却发现是把玩具枪的笑话。
1700454683
1700454684
注意 如果子类不能完整地实现父类的方法,或者父类的某些方法在子类中已经发生“畸变”,则建议断开父子继承关系,采用依赖、聚集、组合等关系代替继承。
1700454685
1700454686
2.子类可以有自己的个性
1700454687
1700454688
子类当然可以有自己的行为和外观了,也就是方法和属性,那这里为什么要再提呢?是因为里氏替换原则可以正着用,但是不能反过来用。在子类出现的地方,父类未必就可以胜任。还是以刚才的关于枪支的例子为例,步枪有几个比较“响亮”的型号,比如AK47、AUG狙击步枪等,把这两个型号的枪引入后的Rifle子类图如图2-4所示。
1700454689
1700454690
1700454691
1700454692
1700454693
图2-4 增加AK47和AUG后的Rifle子类图
1700454694
1700454695
很简单,AUG继承了Rifle类,狙击手(Snipper)则直接使用AUG狙击步枪,源代码如代码清单2-7所示。
1700454696
1700454697
代码清单2-7 AUG狙击枪源码代码
1700454698
1700454699
public class AUG extends Rifle{
1700454700
1700454701
//狙击枪都携带一个精准的望远镜
1700454702
1700454703
public void zoomOut(){
1700454704
1700454705
System.out.println(“通过望远镜察看敌人……”);
1700454706
1700454707
}
1700454708
1700454709
public void shoot(){
1700454710
1700454711
System.out.println(“AUG射击……”);
1700454712
1700454713
}
1700454714
1700454715
}
1700454716
1700454717
有狙击枪就有狙击手,狙击手类的源代码如代码清单2-8所示。
1700454718
1700454719
代码清单2-8 AUG狙击手类的源码代码
1700454720
1700454721
public class Snipper{
1700454722
1700454723
public void killEnemy(AUG aug){
1700454724
1700454725
//首先看看敌人的情况,别杀死敌人,自己也被人干掉
1700454726
1700454727
aug.zoomOut();
1700454728
1700454729
//开始射击
[
上一页 ]
[ :1.70045468e+09 ]
[
下一页 ]