我之前在面向对象的博客中提到过多态,它是面向对象的特性之一(不了解的朋友可以参考这篇文章:http://blog.csdn.net/ITMonkeyKing/article/details/51039436点击打开链接),而多态又被分为方法多态性和对象多态性,
①方法的多态性:重载与覆写
*重载:同一个方法名称,根据不同的参数类型及个数可以完成不同的功能;(是一个类中多态性的表现)
*覆写:同一个方法,根据操作的子类不同,所完成的功能也不同;(是父类与子类间多态的表现)
②对象的多态性:父子类对象的转换
*向上转型:子类对象变为父类对象, 父类 父类对象=子类实例,自动;
*向下转型:父类对象变为子类对象, 子类 子类对象=(子类)父类实例,强制;
我们本篇文章重点介绍的是对象多态性。
(!!!提示:对象的多态性和方法覆写是紧密联系的。)
对象向上转型:
package com.test7;
public class TestDeno2 {
public static void main(String[] args) {
A a=new B();//向上转型
a.print();// 调用被覆写过的方法
}
}
class A{
public void print(){
System.out.println("A 、public void print(){}");
}
}
class B extends A{
public void print(){ //方法覆写
System.out.println("B 、public void print(){}");
}
}
上面的代码中我们实例化的是子类对象“new B()”,而且print()方法被子类覆写了,最终调用的就是被子类覆写过的print()方法。
对象向下转型:
package com.test7;
public class TestDeno2 {
public static void main(String[] args) {
A a =new B();//向上转型
B b=(B) a;//向下转型
b.print();//调用被覆写过的方法
}
}
class A{
public void print(){
System.out.println("A 、public void print(){}");
}
}
class B extends A{
public void print(){ //方法覆写
System.out.println("B 、public void print(){}");
}
}
!!提示:在进行对象转型的操作中,重点观察以下两点:
*实例化的是哪个子类;
*要调用的方法是否是被子类所覆写,覆写后调用的一定是被覆写过的方法
以上总结只针对对象向上转型操作。
!!提示:当对象发生向下转型时,一定要首先发生对象的向上转型关系,否则报错:java.lang.ClasCastException
还好我们在实际开发中,用到向下转型的较少,我们也可以子啊操作中,先判断某一个对象是否是某一个类的实例,使用instanceof关键字,语法结构为:
对象 instanceof 类 =====>返回boolean型
讲解了这么多,那么我们如何在代码中使用我们对象转型的技巧呢 ?下面以一个代码案例来为朋友们介绍:
package com.test7;
public class TestDemo3 {
public static void main(String[] args) {
fun(new E()); //传递子类实例
fun(new F());
}
private static void fun(D d) {// 接收D类子类实例
d.print();
}
}
class D{
public void print(){
System.out.println("A, public void print(){}");
}
}
class E extends D { //定义子类
public void print(){ // 方法覆写
System.out.println("B, public void print(){}");
}
}
class F extends D{ //定义子类
public void print(){ // 方法覆写
System.out.println("C, public void print(){}");
}
}
上面是使用了对象向上转型,大家也可以看看我们不使用对象转型,来完成上面同样的功能,借此可以更好理解为啥要有对象转型。
package com.test7;
public class TestDemo3 {
public static void main(String[] args) {
fun(new E()); //传递子类实例
fun(new F());
}
//!!!!!!!!!!!!!!!!!!!!!!!!!注意了!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
private static void fun(E e) {// 接收E类子类实例
e.print();
}
private static void fun(F f) {// 接收F类子类实例
f.print();
}
}
class D{
public void print(){
System.out.println("A, public void print(){}");
}
}
class E extends D { //定义子类
public void print(){ // 方法覆写
System.out.println("B, public void print(){}");
}
}
class F extends D{ //定义子类
public void print(){ // 方法覆写
System.out.println("C, public void print(){}");
}
}
如果D类有许多的子类,方法就要重载许多次,这显然不好,也不现实。