前言
最近在踩以前学Java没有注意的坑,动态绑定机制是Java的重要特性。同时,我认为,动态绑定机制是多态的根源,对于理解代码有着举足轻重的作用,里面还有很多内容值得深究,简单写点入门内容,后续回在JVM的笔记中进一步完善
目录大纲,自选食用
Demo1
class A { //父类
public int i = 10;
public int sum() {
return getI() + 10;
}
public int sum1() {
return i + 10;
}
public int getI() {
return i;
}
}
class B extends A { //子类
public int i = 20;
public int sum() {
return i + 20;
}
public int sum1() {
return i + 10;
}
public int getI() {
return i;
}
}
//main方法中
A a = new B ();
System.out.println(a.sum()); //40
System.out.println(a.sum1()); //30
Demo2
class A { //父类
public int i = 10;
public int sum() {
return getI() + 10;
}
public int sum1() {
return i + 10;
}
public int getI() {
return i;
}
}
class B extends A {//子类
public int i = 20;
//public int sum() {
// return i + 20;
//}
public int getI() {//子类 getI()
return i;
}
//public int sum1() {
// return i + 10;
//}
}
//main方法中
A a = new B();//向上转型
System.out.println(a.sum()); //40 -> 30
System.out.println(a.sum1()); //30 -> 20
编译时类型&运行时类型
编译时类型由声明该变量时使用的类型决定,运行时类型由实际赋给该变量的对象决定。如果编译时类型和运行时类型不一致,会出现所谓的多态。因为子类其实是一种特殊的父类,因此java允许把一个子类对象直接赋值给一个父类引用变量,无须任何类型转换,或者被称为向上转型,由系统自动完成。引用变量在编译阶段只能调用其编译时类型所具有的方法,但运行时则执行它运行时类型所具有的方法,因此,编写Java代码时,引用变量只能调用声明该变量所用类里包含的方法(方法表)。与方法不同的是,对象的属性则不具备多态性。通过引用变量来访问其包含的实例属性时,系统总是试图访问它编译时类所定义的属性,而不是它运行时所定义的属性。 --------引自《疯狂Java讲义》
动态绑定机制
- 当调用对象方法的时候,该方法会和该对象的内存地址/运行类型绑定
- 当调用对象属性的时候,没有动态绑定机制,哪里声明,哪里使用