首页 > 代码库 > 面向对象的三大特征之三——多态

面向对象的三大特征之三——多态

多态,简单来说就是一种类型表现出多种状态。在Java中多态分为两类。

一、方法多态性——方法的重载和重写。

关于这部分内容已经在前面的内容有过详细的记录,即重复调用的代码块—方法和面向对象的特性之二—继承。

二、对象的多态性——引用类型转换。

1.向上转型(自动转型)——子类对象自动转换为父类对象。

 1 class Father
 2 {
 3     public void speak()
 4     {
 5         System.out.println("我来自父类Father。");
 6     }
 7 }
 8 class Son extends Father
 9 {
10     public void speak()
11     {
12         System.out.println("我来自子类Son。");
13     }
14 }
15 class Daughter extends Father
16 {
17     public void speak()
18     {
19         System.out.println("我来自子类Daughter。");
20     }
21 }
22 public class T02
23 {
24     public static void main(String[] args)
25     {
26         Father p;
27         Son s = new Son();
28         Daughter d = new Daughter();
29         p=s;//子类对象向上类型转换为Father类型
30         p.speak();
31         p=d;
32         p.speak();
33     }
34 }

输出结果如下:

我来自子类Son。
我来自子类Daughter。

可以看出,第26行声明了一个父类对象p,但没有实例化;第27、28行分别声明子类对象s、d并实例化;经过赋值操作,将子类对象向上转型为Father类型。通过p调用其speak方法,实际输出的是子类对象的speak方法。这里就体现了多态性思想。

需要注意的是:上述父类对象只能调用被子类重写的方法,对于子类自己独有的方法,父类对象是无法访问的。

 1 class Father
 2 {
 3     public void speak()
 4     {
 5         System.out.println("我来自父类Father。");
 6     }
 7 }
 8 class Son extends Father
 9 {
10     public void speak()
11     {
12         System.out.println("我来自子类Son。");
13     }
14     public void print()
15     {
16         System.out.println("我是Tom。");
17     }
18 }
19 public class T02
20 {
21     public static void main(String[] args)
22     {
23         Father p;
24         Son s = new Son();
25         p=s;//子类对象向上类型转换为Father类型
26         p.speak();
27         p.print();//错误的,无法访问
28     }
29 }

那么如果非要调用子类的print()方法,那么就要用到下面的向下强制转型,将父类对象赋值给子类对象。

2.向下转型(强制转型)——父类对象强制转换为子类对象。

 1 class Father
 2 {
 3     public void speak()
 4     {
 5         System.out.println("我来自父类Father。");
 6     }
 7 }
 8 class Son extends Father
 9 {
10     public void speak()
11     {
12         System.out.println("我来自子类Son。");
13     }
14     public void print()
15     {
16         System.out.println("我是Tom。");
17     }
18 }
19 public class T02
20 {
21     public static void main(String[] args)
22     {
23         Father p = new Son();
24         p.speak();//自动类型转换
25         ((Son) p).print();//强制类型转换
26     }
27 }

如果同时存在多个子类,就需要使用instanceof关键字来检测转换的安全性,即在每次转换之前都加上一个if判断语句:

if(p instanceof Son)
{
     Son s1 = (Son)p();
}else
{
     System.out.println("无法转换!");
}

3.隐藏——static无法被重写的特性。

当我们不想调用子类中重写的方法,而希望调用父类中原来的方法时,就可以使用隐藏来实现。

 1 class Father
 2 {
 3     public static void speak()
 4     {
 5         System.out.println("我来自父类Father。");
 6     }
 7 }
 8 class Son extends Father
 9 {
10     public static void speak()
11     {
12         System.out.println("我来自子类Son。");
13     }
14 }
15 public class T02
16 {
17 
18     public static void main(String[] args)
19     {
20         Father p = new Son();
21         p.speak();//调用的是父类中的speak()方法
22     }
23 }

输出结果:我来自父类Father。

面向对象的三大特征之三——多态