这个伴随多态的可互换对象我第一眼看上去就很迷惑(这到底是什么鬼?)
在说这个之前我们先来看一段代码(代码原型出自thinking in java):
package demo;
public class Shape {
public void draw(){
System.out.println("shape绘画");
}
public void wipe(){
System.out.println("shape擦除");
}
public void dosomething(Shape shape){
shape.draw();
shape.wipe();
}
}
package demo;
public class rectangle extends Shape {
public void draw(){
System.out.println("rectangle绘画");
}
public void wipe(){
System.out.println("rectangle擦除");
}
}
package demo;
public class TestShap {
public static void main(String[] args) {
rectangle rec=new rectangle();
rec.dosomething(rec);
}
}
控制台输出:
rectangle绘画
rectangle擦除
如果我们仔细看会发现什么?
调用的是shape对象,为啥输出的是这个而不是
shape绘画
shape擦除
这时java多态的一个特性,把一个对象不当做它属的特定类型来看,而是把它看成一个基类的对象来看,使得我们写出不依赖特定类型的代码。
每一个继承基类shape的图形都可以执行draw和wipe方法,方法操作的都是泛化的图形,方法执行不会考虑它是什么图形。所以这样不用担心对象如何处理消息。
我们并不想知道方那一段代码被执行,绘图方法等同地应用于三角形,四边形,等对象,而且对象会已经自身的具体类型来执行恰当的代码。
这个涉及到了非面对对象程序的前期绑定意味着编译器在编译时候,调用一个函数将产生一个具体函数名字的调用,运行时候将这个调用解析到需要调用代码的绝对地址中。
所以面对对象语言采用了后期绑定:即编译器只保证代码的存在和对参数类型和返回值进行检查,但是并不知道具体的代码。(省略了后期绑定的原理,具体请见think in java p9)
所以上面的对象互换就是用到了这个原理。
写的比较随意,如有错误欢迎指正。