您的位置:首页 > 编程语言 > Java开发

[think in java] 第8章 多态

2014-11-02 14:39 381 查看

多态

“封装”通过合并特征和行为来创建新的数据类型。

“多态”的作用则是消除类型之间的耦合关系。

方法调用绑定

定义:将一个方法调用同一个方法主题关联起来被称为绑定。

若在程序执行前进行绑定(如果有的话,由编译器和链接程序实现),叫前期绑定。在运行时根据对象的类型进行绑定称为后期绑定,或运行时绑定。java中的多态就是通过动态绑定实现的。

java中除了static方法和final方法(private 方法属于final方法)之外,其他所有方法都是后期绑定。



缺陷:域与静态方法

一旦你了解了多态机制,你可能会认为所有事物都是可以多态的发生的。然而,只有普通的方法调用是可以多态的。如果你访问某个域field,这个访问将在编译期进行解析。看下面的例子:

class Super{
public int filed = 0;
public int getFiled(){
return filed;
}
}

class Sub extends Super{
public int filed = 1;
public int getFiled(){
return filed;
}

public int getSuperFiled(){
return super.filed;
}
}
public class FiledAccess {

public static void main(String [] agrs){
Super sup = new Sub();
System.out.println("sup.field = " + sup.filed + ", sup.getField() = "+
sup.getFiled());

Sub sub = new Sub();
System.out.println("sub.field = " + sub.filed + ", sub.getField() = "+
sub.getFiled() + ", sub.getSuperField() = " + sub.getSuperFiled());

}

}
sup.field = 0, sup.getField() = 1
sub.field = 1, sub.getField() = 1, sub.getSuperField() = 0


当Sub转型为Super引用时,任何域访问操作都将由编译器解析,因此不是多态的。在本例中,为Super.field和Sub.field分配了不同的存储空间。这样,Sub实际上包含两个成为field的域:他自己的和它从Super处得到的。然而在引用Sub中的filed时所产生的默认域并非Super版本的field域。因此,为了得到Super.filed,必须显示的指明super.field。
这个问题看起来很容易令人混淆,但是实际中却并不常发生。因为根据设计原则,我们常常将所有的域设置为private的,因此不能直接访问他们,只能通过方法来访问。

总结:方法多态,域不多态访问。

静态方法同样不具有多态性。因为静态方法是与类相关联的,而不是与单个对象相关联。看下面的例子消化一下^.^~:

class StaticSuper{
public static String staticGet(){
return "Base staticGet()";
}

public String dynamicGet(){
return "Base dynamicGet()";
}
}

class StaticSub extends StaticSuper{
public static String staticGet(){
return "Derived staticGet()";
}

public String dynamicGet(){
return "Derived dynamicGet()";
}
}
public class StaticPolymorphism {
public static void main(String [] args){
StaticSuper sup = new StaticSub();
System.out.println(sup.staticGet());
System.out.println(sup.dynamicGet());
}
}

output:
Base staticGet()
Derived dynamicGet() 


参考:《thinking in java》
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: