Java多态:向上转型

一、定义

向上转型:子类对象转为父类,父类可以是接口。 如:Father f = new Son();

向下 转型:父类对象转为子类。 如: Son s = (Son)f; 

注:括号内容为强制转型,向下转型必需要这样做。向上转型则不需要这样做

二、 向上转型使用举例

 

 1  public class Human {
 2 
 3         public void sleep() {
 4             System.out.println("Human sleep..");
 5         }
 6 
 7         public static void main(String[] args) {
 8             Human h = new Male();// 向上转型
 9             h.sleep();
10              Male m = new Male();
11             m.sleep();
12              // h.speak();此方法不能编译,报错说Human类没有此方法
13         }
14      }
15 
16 class Male extends Human {
17           public void sleep() {
18              System.out.println("Male sleep..");
19          }
20 
21         public void speak() {
22              System.out.println("I am Male");
23          }
24      }

 

 运行结果:

       Male sleep..
        Male sleep..

结果分析:

   向上转型会丢失子类特有的方法(如,上述例子中的h.speak()),但是子类重写了父类的方法,子类方法有效,向上转型只能引用父类对象的属性,要引用子类对象属性,则要写getter函数。要想使用子类特有的方法,则需要将其向下转型。

注意:只有非private方法才可以被覆盖,若子类对父类的private方法进行重载,则,当使用向上转型时,编译器将不会报错,并且将子类重载的方式视为新的子类方法。

问题:

既然向上转型使用起来这么麻烦,并且在使用过程中会丢失子类特有的方法,在使用子类特有的方法时,还必须对其进行向下转型,为什么在使用时不直接定义Son s = new Son();呢??

三、向上转型使用举例二

 

 1 package polymorphism.music;
 2 
 3 public enum Note
 4 {
 5      MIDDLE_C, C_SHARP, B_FLAT;
 6 }
 7 
 8 /////////////////////////////////////////////
 9 
10 package polymorphism.music;
11 
12 class Instrument
13 {
14      public void play(Note n)
15      {
16          System.out.println("Instrument.play()");
17      }
18 }
19 
20 /////////////////////////////////////////////
21 
22 package polymorphism.music;
23 
24 public class Wind extends Instrument
25 {
26      public void play(Note n)
27      {
28          System.out.println("Wind.play()" + n);
29      }
30 }
31 
32 /////////////////////////////////////////////
33 
34 package polymorphism.music;
35 
36 public  class Music
37 {
38      public static void tune(Instrument i)
39      {
40          i.play(Note.MIDDLE_C);
41      }
42 
43     public static void main(String[] args)
44      {
45          Wind flute = new Wind();
46          tune(flute);
47      }
48 }

运行结果:

Wind.play()MIDDLE_C

结果分析:

Music.tune()方法接收一个Instrument的引用,同时也接受任何导出的Instrument的类。在main中,当一个Wind引用tune()方法时,便出现了该情况,因此不需要任何类型转化。其中,tune(flute)便是一个向上转型。

在进行向上转型时会出现忘记对象类型这种情况。虽然让tune()方法直接接受一个Wind引用作为自己参数更为直观,但是这样会产生一个问题:如果这样做了,就需要对Instrument的每种类型都编写一个新的tune()方法。

 

posted @ 2019-05-24 13:26  小鹏_Leo  阅读(247)  评论(0编辑  收藏  举报