14章.类型信息(1)
运行时类型信息使得你可以在程序运行时发现和使用类型信息。
java在运行时识别对象和类的信息有两种方式:(1)“传统的”RTTI,它假定我们在编译时已经知道了所有的类型;(2)“反射”机制,它允许我们在运行时发现和使用类的信息。
为什么需要RTTI(Run-Time-Type-Information)
面向对象编程的基本目的是:让代码只操纵基类的引用,这样如果要在基类下面添加新类时,不会影响原来的代码。
例如:

图中的动物是基类,位于顶部,派生类向下扩展。
先看一下,如果我们不操纵基类,会有什么后果?
如果我们写代码操纵的不是动物基类,而是动物下的具体的动物派生类,如:长颈鹿等,势必会导致我们的代码一遍一遍的改变。因为长颈鹿的跑绝不等同于花豹的跑,当你想让花豹跑时,你得改变长颈鹿的跑,如此以来,我们面向对象编程的目的就达不到了。
那么怎样才能算是面向对象编程?
我们只需要操纵动物中动态绑定的跑行为,这样在具体的动物中再去具体覆盖跑行为即可。这样真正运行时,其实运行的是派生类中具体的跑行为。我管这一招叫“瞒天过海”。
联系生活举例如下:
这里举例为特洛伊。开战之前,怎样将士兵运进城内呢?这里就是将真正的士兵装入人形木马内(特洛伊战争是装入了木马中),这样就不用一个一个士兵的进城,只需要将人形木马运入城中即可,这就好比是编译完成了!那么进城之后夜晚就要开战了,怎么向士兵发号进攻命令?一个一个士兵通知吗?不需要,只需要对人形木马喊一声,装在里面的士兵都听见了,于是他们发动了进攻,每一个士兵的进攻动作(炮手,弓箭手,步行兵等)并不相同,但他们都知道自己是在执行进攻命令。
代码举例如下:
1 package Fourty; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 6 abstract class Animal { 7 void run(){ 8 System.out.println(this + ".run()"); 9 } 10 } 11 12 class Giraffe extends Animal { 13 public String toString() { 14 return "GIRAFFE"; 15 } 16 } 17 18 class Leopard extends Animal { 19 public String toString() { 20 return "LEOPARD"; 21 } 22 } 23 24 class Ostrich extends Animal { 25 public String toString() { 26 return "OSTRICH"; 27 } 28 } 29 30 public class Fourty1 { 31 public static void main(String[] args) { 32 // 把长颈鹿、花豹、鸵鸟装入 33 List<Animal> animals = new ArrayList<>(); 34 animals.add(new Giraffe()); 35 animals.add(new Leopard()); 36 animals.add(new Ostrich()); 37 // 执行跑的行为 38 for (Animal animal : animals) { 39 animal.run(); 40 } 41 } 42 }
金麟岂是池中物,
一遇风云便化龙。
九霄龙吟惊天变,
风云际会浅水游。

浙公网安备 33010602011771号