多态(1)——向上转型和忘记对象类型
多态通过分离做什么和怎么做,将接口与实现分离开来,改善了代码的结构和可读性,还能创建可扩展的程序——即在创建的时候和添加新功能的时候都可以“生长”的程序。
封装是指,一种将抽象性函数接口的实现细节部分包装、隐藏起来的方法。同时,它也是一种防止外界调用端,去访问对象内部实现细节的手段。
多态的作用则是消除这些类型之间的耦合关系。
继承允许将对象视为它自己本身的类型或基类型进行处理,一份代码可以无差别运行在不同类型上。
多态则是允许一种类型表现出与其他类型之间的区别,这些区别是通过方法行为不同表现出来的,这些方法都可以通过同一基类的调用。
一、向上转型
对某个对象的引用视为其基类型成为向上转型
看下面有关乐器的例子:
1 //新建enum的枚举类 2 public enum Note { 3 MIDDLE_C,C_SHARP,D_FLAT; 4 }
1 class Instrument{ 2 public void play(Note n) { 3 System.out.println("Instrment.play()"); 4 } 5 } 6 class Wind extends Instrument{ 7 public void play(Note n) { 8 System.out.println("wind.play()" + n); 9 } 10 } 11 public class Music { 12 public static void tune(Instrument i) { 13 i.play(Note.MIDDLE_C); 14 } 15 public static void main(String[] args) { 16 Wind flute = new Wind(); 17 tune(flute); 18 } 19 }
运行结果:
wind.play()MIDDLE_C
可以看出,Music.tune()接受了Instrument的引用,同时,接受Instrument导出的Wind类,当Wind的引用传递到tune()方法时,不需要任何的转换,所以,Instrument的接口存在于Wind中。
二、忘记对象类型
1 class Instrument{ 2 public void play(Note n) { 3 System.out.println("Instrment.play()"); 4 } 5 } 6 class Wind extends Instrument{ 7 public void play(Note n) { 8 System.out.println("Wind.play()" + n); 9 } 10 } 11 class Stringed extends Instrument{ 12 public void play(Note n) { 13 System.out.println("Stringed.play()" + n); 14 } 15 } 16 class Brass extends Instrument{ 17 public void play(Note n) { 18 System.out.println("Brass.play()" + n); 19 } 20 } 21 public class Music { 22 public static void tune(Instrument i) { 23 i.play(Note.MIDDLE_C); 24 } 25 public static void tune(Wind i) { 26 i.play(Note.MIDDLE_C); 27 } 28 public static void tune(Stringed i) { 29 i.play(Note.MIDDLE_C); 30 } 31 public static void tune(Brass i) { 32 i.play(Note.MIDDLE_C); 33 } 34 public static void main(String[] args) { 35 Wind flute = new Wind(); 36 Stringed violin = new Stringed(); 37 Brass frenchHorn = new Brass(); 38 tune(flute); 39 tune(violin); 40 tune(frenchHorn); 41 } 42 }
运行结果:
Wind.play()MIDDLE_C
Stringed.play()MIDDLE_C
Brass.play()MIDDLE_C
这样,是无法看到Wind,Stringed,Brass类型的基类Instrument
这样做是可以的,但必须对每一个特定的新类型写特定的tune()方法,这将造成极大的工作量,而且如果忘记重载某个方法,编译器不会返回错误信息,整个类型变得难以操纵。

浙公网安备 33010602011771号