纸上得来终觉浅
Think in Java第八章 多态
1.实现向上转型的原因是由于动态绑定的存在,就是在运行时根据对象的类型对其进行绑定,编译器不知道对象的类型,但是运行中,能根据对象类型调用正确的方法并调用;
2.除了Static和Final(Private方法属于final,和final一样,不能被重写)方法,其他所有方法都是动态绑定;这两种方法无法实现多态(无法实现动态绑定),但是更详细的原因如下:
1)Static的访问是根据类直接访问,它不会根据基类存储的类型调用相关的方法,而是直接调用类中的方法,但是还是可以被重写的;
2)Final因为不能重写,所以即使子类中有,也是新的方法,也无法实现多态;
这里总结下Final作用:
1)上篇说到的防止被覆盖;
2)关闭动态绑定,告诉编译器不需要对其进行动态绑定,这样编译器可以为final方法调用生成更有效的代码(没有测试过。。。)
3.构造器中调用的方法最好是Final类型(Private)的方法:
如果构造器中调用普通的方法,那么根据上篇文章中讲述的类的初始化顺序,那么顺序是:父类非静态成员变量初始化-->父类构造函数-->子类非静态成员变量初始化-->子类构造函数,在执行父类构造函数时,调用了普通的方法, 而子类重写了这个方法,所以它就是去调用子类的这个方法,如果子类这个方法中用到了非静态成员变量,这个时候其实还没有到子类非静态成员变量初始化, 就可能导致不想要的后果,如下:
package roadArchitectWeb.Test;
class Test extends Test1{
private int a = 10;
public void doTest(){
System.out.println("Test.doTest()extend:"+a);
}
public Test(){
System.out.println("Test.Test():"+a);
}
}
public class Test1{
public void doTest(){
System.out.println("Test1.doTest()");
}
public Test1(){
doTest();
}
public static void main(String[] args) {
Test test = new Test();
}
}
结果如下:
Test.doTest()extend:0
Test.Test():10
第一行结果,这个时候a还没有初始化,所以为0;这可能不是原来想要的结果