1.动态绑定(后期绑定)
Java中除了static方法和final方法(private方法属于final方法)之外,其他方法都是后期绑定。我们不必像C++一样判断是否进行动态绑定,因为它会自动发生。
假设基类Shape派生出了具体类Circle、Square、Triangle。所以,基类对象(如Shape对象)在运行时执行什么样的代码,是由引用所指向的具体对象(如Circle,Square,Triangle)决定的。
class B extends A 继承过后通常会定义一些父类没有的成员或者方法。
A a = new B(),a是一个父类对象的实例,因而不能访问子类定义的新成员或方法,只能访问A中的方法。那么又和A a = new A();有什么区别呢?
假如这样定义:
class A{
int i;
void f(){}
}
class B extends A{
int j;
void f(){}//重写
void g(){}
}
(1)B b = new B();
b就是子类对象的实例,不仅能够访问自己的属性和方法,也能够访问父类的属性和方法。诸如b.i,b.j,b.f(),b.g()都是合法的。此时 b.f()是访问的B中的f()
(2)A a = new B();
a虽然是用的B的构造函数,但经过upcast,成为父类对象的实例,不能访问子类的属性和方法。a.i,a.f()是合法的,而a.j,a.g()非 法。此时访问a.f()是访问B中的f()
A a = new B(); 这条语句,实际上有三个过程:
(1) A a;将a声明为父类对象,只是一个引用,未分配空间
(2) B temp = new B();通过B类的构造函数建立了一个B类对象的实例,也就是初始化
(3) a = (A)temp;将子类对象temp转换未父类对象并赋给a,这就是上传(upcast),是安全的。
经过以上3个过程,a就彻底成为了一个A类的实例。
2.final
(1)final方法
将某个方法声明为final的原因只要有两点:
1.可以防止其他人覆盖此方法
2.可以有效关闭动态绑定
(2)final类
当整个类的定义为final时,表明你能继承该类,不会有任何变动。
(3)final数据
1.对于基本类型,final使数值恒定不变,对于对象引用,final使引用恒定不变(即当final已被初始化指向一个对象后,便不能再指向其他对象,但是对象本身是可以改变的)。
2.必须在定义时进行初始化