Java多态
1,多态是继数据抽象和继承之后的第三种基本特征。
封装通过合并特征和行为来创建新的数据类型,而多态则是数据类型之间的耦合关系。
继承允许对象视为自己本身的类型或者其积类型来处理,而同一代吗则可以毫无差别的运行在这些不同的类型之上了。
import java.util.*;
enum Node{
MIDDLE_C,C_SHARP,B_FLAT
}
class Instructment{
public void play(Node n){
System.out.println("Instructment.play() "+n);
}
}
class Winds extends Instructment{
public void play(Node n){
System.out.println("Wind.play() "+n);
}
}
public class Music{
public static void tune(Instructment i){
i.play(Node.MIDDLE_C);
}
public static void main(String[] args){
Winds flute=new Winds();
tune(flute);
}
}
后期绑定(动态绑定或运行时绑定):在运行时根据对象的类型进行绑定。
Java中除了static和final方法(private方法属于final方法)之外,其他所有的方法都是后期绑定。这意味着,通常情况下我们不必判断其是否应该进行自动绑定,它会自动发生。
import java.util.*;
class BaseShape{
public void draw(){
System.out.println("BaseShape.draw()");
}
public void erase(){
System.out.println("BaseShape.erase()");
}
}
class Circle extends BaseShape{
public void draw(){
System.out.println("Circle.draw()");
}
public void erase(){
System.out.println("Circle.erase()");
}
}
class Square extends BaseShape{
public void draw(){
System.out.println("Square.draw()");
}
public void erase(){
System.out.println("Square.erase()");
}
}
class Triangle extends BaseShape{
public void draw(){
System.out.println("Triangle.draw()");
}
public void erase(){
System.out.println("Triangle.erase()");
}
}
public class Shape{
private static Random rand=new Random(47);
public static BaseShape next(){
switch (rand.nextInt(3)){
case 0:
return new Circle();
case 1:
return new Square();
case 2:
return new Triangle();
}
return null;
}
public static void main(String[] args){
BaseShape[] s=new BaseShape[9];
for(int i=0;i<s.length;i++)
s[i]=next();
for(BaseShape sh:s)
sh.draw();
}
}
随机选择几何形状是为了说明编译器不需要获得任何特殊信息就能进行正确地调用。
2,只有普通的方法调用可以是多态的,域与静态方法没有多态性。
import java.util.*;
class Super{
public int field=0;
public int getField(){
return field;
}
}
class Sub extends Super{
public int field=1;
public int getField(){
return field;
}
public int getSuperField(){
return super.field;
}
}
public class FieldAccess{
public static void main(String[] args){
Super sup=new Sub();//upcast
System.out.println("sup.field="+sup.field+", sup.getField()="+sup.getField());
Sub sub=new Sub();
System.out.println("sub.field="+sub.field+", sub.getField()="+sub.getField()+
", sub.getSuperField()="+sub.getSuperField());
}
}
任何域访问操作都将由编译器解析,因此不是多态的。
同样静态方法属于类,并未与单个对象相关联,所以也不是多态的。