Java是面向对象的语言,在Java中一切都是对象。面向对象编程有三大特性:封装、继承和多态。封装即对外部隐藏了类的具体实现,同时起到了保护数据的作用;继承即重用父类的代码,同时也提供了实现多态的基础;多态即在程序中定义的引用变量所指向的类型或者调用的方法在编程时并不确定,而在程序运行时才调用,也就是说在程序运行时才决定到底调用确定的类型已经该类型的具体方法。
多态的实现方法:上面提到继承时多态的实现基础,所以多态的实现可以通过继承,包括继承类和继承接口。
下面通过一个简单的例子说明一下Java多态的特性。
public abstract class Abstract {
public Abstract(){}
protected abstract void sayWord();
}
public interface Interface {
void sayMessage();
}
public class Entity extends Abstract implements Interface{
protected void sayWord(){
System.out.println("hello");
}
public void sayHello(){
System.out.println("i am hello");
}
public void sayMessage() {
System.out.println("i am world");
}
}
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
Abstract a = new Entity();
Interface i = new Entity();
Entity e = new Entity();
System.out.println(e instanceof Abstract);
System.out.println(e instanceof Interface);
System.out.println(a instanceof Entity);
System.out.println(a instanceof Interface);
System.out.println(i instanceof Entity);
System.out.println(i instanceof Abstract);
sayAbstract(a);
sayEntity(e);
sayInterface(i);
}
public static void sayAbstract(Abstract a) {
a.sayWord();
if (a instanceof Entity) {
((Entity)a).sayHello();
((Entity) a).sayMessage();
}
}
public static void sayEntity(Entity e) {
e.sayHello();
e.sayWord();
e.sayMessage();
}
public static void sayInterface(Interface i) {
i.sayMessage();
if (i instanceof Entity) {
((Entity) i).sayHello();
((Entity) i).sayWord();
}
}
}
通过程序运行结果可以看出通过不同的类型进行初始化的对象也都属于子类类型已经子类所继承的父类或者接口。这就是多态,在程序运行时可以确定对象所指向的具体类型。
同时我们可以看到在子类中有一个自己独有的方法sayHello(),但是在Entity父类或者接口实例化的对象中,要想调用改方法必须进行强制转型。这是因为在JVM加载类后,当调用方法时,是根据方法表来获取方法的位置。父类Abstract和子类Entity公有的方法可以直接调用,因为通过方法表先找到的是指向父类的方法,进一步的,在运行时有通过方法表找到了子类的具体实现。所以通过父类实例化子类的对象可以调用共有方法,但必须强制转型后才能调用子类的独有方法。
通过上面的例子,我们可以看出通过多态可以对程序进行扩充,在编程时我们可以使程序更加易于维护。众多的设计模式中也都用到了Java的多态性,这里就不叙述了。