🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
## [向上转型回顾](https://lingcoder.gitee.io/onjava8/#/book/09-Polymorphism?id=%e5%90%91%e4%b8%8a%e8%bd%ac%e5%9e%8b%e5%9b%9e%e9%a1%be) 在上一章中,你看到了如何把一个对象视作它的自身类型或它的基类类型。这种把一个对象引用当作它的基类引用的做法称为向上转型,因为继承图中基类一般都位于最上方。 同样你也在下面的音乐乐器例子中发现了问题。即然几个例子都要演奏乐符(**Note**),首先我们先在包中单独创建一个 Note 枚举类: ~~~ // polymorphism/music/Note.java // Notes to play on musical instruments package polymorphism.music; public enum Note { MIDDLE_C, C_SHARP, B_FLAT; // Etc. } ~~~ 枚举已经在”第 6 章初始化和清理“一章中介绍过了。 这里,**Wind**是一种**Instrument**;因此,**Wind**继承**Instrument**: ~~~ // polymorphism/music/Instrument.java package polymorphism.music; class Instrument { public void play(Note n) { System.out.println("Instrument.play()"); } } // polymorphism/music/Wind.java package polymorphism.music; // Wind objects are instruments // because they have the same interface: public class Wind extends Instrument { // Redefine interface method: @Override public void play(Note n) { System.out.println("Wind.play() " + n); } } ~~~ **Music**的方法`tune()`接受一个**Instrument**引用,同时也接受任何派生自**Instrument**的类引用: ~~~ // polymorphism/music/Music.java // Inheritance & upcasting // {java polymorphism.music.Music} package polymorphism.music; public class Music { public static void tune(Instrument i) { // ... i.play(Note.MIDDLE_C); } public static void main(String[] args) { Wind flute = new Wind(); tune(flute); // Upcasting } } ~~~ 输出: ~~~ Wind.play() MIDDLE_C ~~~ 在`main()`中你看到了`tune()`方法传入了一个**Wind**引用,而没有做类型转换。这样做是允许的——**Instrument**的接口一定存在于**Wind**中,因此**Wind**继承了**Instrument**。从**Wind**向上转型为**Instrument**可能“缩小”接口,但不会比**Instrument**的全部接口更少。