首页 > 代码库 > 父类的引用对象指向子类的对象

父类的引用对象指向子类的对象

  在java的多态中,经常会看到父类的引用对象指向子类的对象,一开始很迷茫,因为按照之前所学的知识,父类的引用对象指向自身对象或者子类的引用对象指向自身对象都不难理解,因此为了方便理解,下面举了一个例子:水杯和水壶的比喻。

       技术分享

  下面的一段代码来实现这个比喻:

 1 public class Kettle {
 2     public Kettle(){
 3         System.out.println("水壶容量有2升");
 4     }
 5 }
 6 
 7 public class Cup extends Kettle {
 8     public Cup(){
 9         System.out.println("水杯容量为0.5升");
10     }
11 }
12 
13 public class Test {
14     public static void main(String[] args) {
15         Kettle k = new Kettle(); //父类的引用对象指向自身:把2升水倒入到水壶中,不会溢出
16         Cup c = new Cup();//子类的引用对象指向自身:把0.5升的水倒入到水杯中,不会溢出
17         Kettle k1 = new Cup(); //父类的引用对象指向子类:把0.5升的水倒入到水壶中,不会溢出
18         Kettle k2 = (Kettle)c; //父类的引用对象指向子类中继承父类的那一部分对象:把水杯中的0.5升水倒入到水壶中,不会溢出
19         Cup c2 = (Cup)k; //子类的引用对象指向父类对象,报错,不能转换类型:水壶里面的水不能倒入到水杯中,会溢出
20         Cup c3 = (Cup)k2;//相当于Cup c3 = (Cup)(Kettle)c,子类的引用对象指向子类中继承父类的那一部分对象:把水壶中0.5升的水倒入到水杯中,不会溢出
21     }
22 }

 

上面的代码运行结果如下:

1 水壶容量有2升
2 水壶容量有2升
3 水杯容量为0.5升
4 水壶容量有2升
5 水杯容量为0.5升
6 Exception in thread "main" java.lang.ClassCastException: mycom.Kettle cannot be cast to mycom.Cup
7     at mycom.Test.main(Test.java:9)

其中报错的哪一行就是Cup c2 = (Cup)k,由于无法转换类型。

  下面来改写一下代码

 1 public class Kettle {
 2     public void holeWater(){
 3         System.out.println("水壶有装水的功能");
 4     }
 5 }
 6 
 7 public class Cup extends Kettle {
 8     public void holeWater(){
 9         System.out.println("水杯也有装水的功能");
10     }
11     public void drinkWater(){
12         System.out.println("水杯可以拿来喝水的功能");
13     }
14 }
15 
16 
17 public class Test {
18     public static void main(String[] args) {
19         Kettle k = new Cup(); //父类的引用对象指向子类
20         k.holeWater();
21         k.darinkWater(); //报错
22     }
23 }

首先,要实现多态,必须有三个条件:父类引用、子类对象、方法覆盖,在上面的程序中,k调用holeWater方法可以正常编译,因为满足三个条件,而后面的drinkWater方法由于在父类中没有,因此在调用时,会报错,没有满足“方法覆盖"的条件,多态实际上是一种机制,在编译时刻,会生成一张虚拟表,来记录所有覆盖的方法,没有被覆盖的方法是不会记录到这张表的.若一个父类引用调用了没有覆盖的子类方法,那么是不符合该表的,那么编译时刻就会报错. 在执行程序的时候,虚拟机会去这张虚拟表中找覆盖的方法,比如引用中实际上存的是一个子类对象引用,那么就会去找子类中的相应的覆盖的方法来执行。

  用父类的引用对象指向子类对象,可以隐藏各个对象不同的细节,专注于共同的属性,这就是面向对象的思想。

父类的引用对象指向子类的对象