什么是多态
1.面向对象的三大特性:
封装、继承、多态,多态是建立在继承之上的,封装和继承几乎都是为多态而准备的。多态性在面向对象中是一个最重要的概念。
2. 多态,指允许不同类的对象对同一消息作出相应。
即同一消息可以根据发送消息的不同而采用多种不同的行为方式。简单地说,就是指同一行为在不同对象下所产生的不同表现形式。
比如,按下F1键的行为:
在Flash界面下弹出的是AS3的帮助文档;
在Word界面下弹出的是Word帮助;
在Windows界面下弹出的是Windows帮助和支持。
可见,同一行为在不同的对象下产生的结果会不同。
3.多态的作用:
消除类型之间的耦合关系。
4.多态存在的三个必要条件:
继承;重写;父类引用指向子类对象(向上转型)。
当使用多态方式调用方法时,首先检查父类中是否有该方法。如果没有,则编译错误;如果有,再去调用子类的同名方法。
**在进行对象的向下转型前,必须首先发生对象的向上转型,否则将出现对象转换异常。 **
5.对象多态性的两种类型 (class B extends A)
(1)向上转型:子类对象 父类对象
格式:子类 子类对象 = new子类 ;
父类 父类对象 = 子类实例 ;
(B b = new B;A a = b;)
或
父类 父类对象 = new 子类;
(A a = new B;)
具体代码如下:
class A{
public void fun1() {
System.out.println("A-->public void fun1()");
}
public void fun2() {
this.fun1();
}
};
class B extends A{
public void fun1() {
System.out.println("B-->public void fun1()");
}
public void fun3() {
System.out.println("B-->public void fun3()");
}
};
public class PolDemo01 {
public static void main(String[] args) {
// TODO Auto-generated method stub
B b = new B();
A a = b;
a.fun1();
}
}
运行结果:
B-->public void fun1()
(2)向下转型:父类对象 子类对象
格式:子类 子类对象 = (子类)父类实例;
(B b = (B) a)【前提:A a = new B;】
具体代码如下:
package 多态;
class A{
public void fun1() {
System.out.println("A-->public void fun1()");
}
public void fun2() {
this.fun1();
}
};
class B extends A{
public void fun1() {
System.out.println("B-->public void fun1()");
}
public void fun3() {
System.out.println("B-->public void fun3()");
}
};
public class PolDemo02 {
public static void main(String[] args) {
// TODO Auto-generated method stub
A a = new B();
B b = (B) a;
b.fun1();
b.fun2();
b.fun3();
}
}
运行结果:
B-->public void fun1()
B-->public void fun1()
B-->public void fun3()
多态的优点
1.可替换性
即多态对已存在的代码具有可替换性。例如,多态对圆Circle类工作,对其他任何圆形几何体,如圆环,也同样工作。
2.可扩充性
即多态对代码具有可扩充性。增加新的子类不影响已存在类的多态性、继承性,以及其他特性的运行和操作。新添加的子类更容易获得多态功能。例如,在实现圆锥、半圆锥以及半球体的多态的基础上,很容易添加球体类的多态性。
3.接口性
即超类通过方法签名,向子类提供了一个共同接口,由子类来完善或者覆盖它而实现。
4.灵活性
即灵活多样的操作,提高了使用的效率。
5.简化性
即简化了对应用软件的代码编写和修改过程,尤其在处理大量对象的运算和操作方面。
对象向下转型的要求
范例:错误的转型
package 多态;
class A{
public void fun1() {
System.out.println("A-->public void fun1()");
}
public void fun2() {
this.fun1();
}
};
class B extends A{
public void fun1() {
System.out.println("B-->public void fun1()");
}
public void fun3() {
System.out.println("B-->public void fun3()");
}
};
public class PolDemo03 {
public static void main(String[] args) {
// TODO Auto-generated method stub
A a = new A();
B b = (B) a;
b.fun1();
b.fun2();
b.fun3();
}
}
运行结果:
Exception in thread "main" java.lang.ClassCastException: 多态.A cannot be cast to 多态.B
at 多态.PolDemo03main(PolDemo02.java:23)
由代码可知,A类对象是由A类本身进行实例化的,然后将A类的实例化对象强制转换成子类对象。这样在语法上是没有任何错误的,但父类用其本身实例化自己的对象,但它并不知道自己的子类是谁,在转换上肯定会出现错误,所以要将两个对象建立好关系,即在声明父类对象时先发生向上转型关系“A a = new B()”,相当于用子类去实例化父类对象,父类就知道自己有一个B类子类,那么在进行转化时就不会再有错误产生了。