ThinkSSL🔒 一键申购 5分钟快速签发 30天无理由退款 购买更放心 广告
### [可扩展性](https://lingcoder.gitee.io/onjava8/#/book/09-Polymorphism?id=%e5%8f%af%e6%89%a9%e5%b1%95%e6%80%a7) 现在让我们回头看音乐乐器的例子。由于多态机制,你可以向系统中添加任意多的新类型,而不需要修改`tune()`方法。在一个设计良好的面向对象程序中,许多方法将会遵循`tune()`的模型,只与基类接口通信。这样的程序是可扩展的,因为可以从通用的基类派生出新的数据类型,从而添加新的功能。那些操纵基类接口的方法不需要改动就可以应用于新类。 考虑一下乐器的例子,如果在基类中添加更多的方法,并加入一些新类,将会发生什么呢: ![乐器继承图](https://lingcoder.gitee.io/onjava8/images/1562252767216.png) 所有的新类都可以和原有类正常运行,不需要改动`tune()`方法。即使`tune()`方法单独存放在某个文件中,而且向**Instrument**接口中添加了新的方法,`tune()`方法也无需再编译就能正确运行。下面是类图的实现: ~~~ // polymorphism/music3/Music3.java // An extensible program // {java polymorphism.music3.Music3} package polymorphism.music3; import polymorphism.music.Note; class Instrument { void play(Note n) { System.out.println("Instrument.play() " + n); } String what() { return "Instrument"; } void adjust() { System.out.println("Adjusting Instrument"); } } class Wind extends Instrument { @Override void play(Note n) { System.out.println("Wind.play() " + n); } @Override String what() { return "Wind"; } @Override void adjust() { System.out.println("Adjusting Wind"); } } class Percussion extends Instrument { @Override void play(Note n) { System.out.println("Percussion.play() " + n); } @Override String what() { return "Percussion"; } @Override void adjust() { System.out.println("Adjusting Percussion"); } } class Stringed extends Instrument { @Override void play(Note n) { System.out.println("Stringed.play() " + n); } @Override String what() { return "Stringed"; } @Override void adjust() { System.out.println("Adjusting Stringed"); } } class Brass extends Wind { @Override void play(Note n) { System.out.println("Brass.play() " + n); } @Override void adjust() { System.out.println("Adjusting Brass"); } } class Woodwind extends Wind { @Override void play(Note n) { System.out.println("Woodwind.play() " + n); } @Override String what() { return "Woodwind"; } } public class Music3 { // Doesn't care about type, so new types // added to the system still work right: public static void tune(Instrument i) { // ... i.play(Note.MIDDLE_C); } public static void tuneAll(Instrument[] e) { for (Instrument i: e) { tune(i); } } public static void main(String[] args) { // Upcasting during addition to the array: Instrument[] orchestra = { new Wind(), new Percussion(), new Stringed(), new Brass(), new Woodwind() }; tuneAll(orchestra); } } ~~~ 输出: ~~~ Wind.play() MIDDLE_C Percussion.play() MIDDLE_C Stringed.play() MIDDLE_C Brass.play() MIDDLE_C Woodwind.play() MIDDLE_C ~~~ 新方法`what()`返回一个带有类描述的**String**引用,`adjust()`提供一些乐器调音的方法。 在`main()`方法中,当向**orchestra**数组添加元素时,元素会自动向上转型为**Instrument**。 `tune()`方法可以忽略周围所有代码发生的变化,仍然可以正常运行。这正是我们期待多态能提供的特性。代码中的修改不会破坏程序中其他不应受到影响的部分。换句话说,多态是一项“将改变的事物与不变的事物分离”的重要技术。