🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
### [Instrument 作为接口](https://lingcoder.gitee.io/onjava8/#/book/10-Interfaces?id=instrument-%e4%bd%9c%e4%b8%ba%e6%8e%a5%e5%8f%a3) 回顾下乐器的例子,使用接口的话: ![类图](https://lingcoder.gitee.io/onjava8/images/1562737974623.png) 类**Woodwind**和**Brass**说明一旦实现了某个接口,那么其实现就变成一个普通类,可以按常规方式扩展它。 接口的工作方式使得我们不需要显式声明其中的方法为**public**,它们自动就是**public**的。`play()`和`adjust()`使用**default**关键字定义实现。在 Java 8 之前,这些定义要在每个实现中重复实现,显得多余且令人烦恼: ~~~ // interfaces/music5/Music5.java // {java interfaces.music5.Music5} package interfaces.music5; import polymorphism.music.Note; interface Instrument { // Compile-time constant: int VALUE = 5; // static & final default void play(Note n) // Automatically public System.out.println(this + ".play() " + n); } default void adjust() { System.out.println("Adjusting " + this); } } class Wind implements Instrument { @Override public String toString() { return "Wind"; } } class Percussion implements Instrument { @Override public String toString() { return "Percussion"; } } class Stringed implements Instrument { @Override public String toString() { return "Stringed"; } } class Brass extends Wind { @Override public String toString() { return "Brass"; } } class Woodwind extends Wind { @Override public String toString() { return "Woodwind"; } } public class Music5 { // Doesn't care about type, so new types // added to the system still work right: static void tune(Instrument i) { // ... i.play(Note.MIDDLE_C); } 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()`被修改为`toString()`方法,因为`toString()`实现的正是`what()`方法要实现的逻辑。因为`toString()`是根基类**Object**的方法,所以它不需要出现在接口中。 注意到,无论是将其向上转型为称作**Instrument**的普通类,或称作**Instrument**的抽象类,还是叫作**Instrument**的接口,其行为都是相同的。事实上,从`tune()`方法上看不出来**Instrument**到底是一个普通类、抽象类,还是一个接口。