首先看繼承代碼
class Instrument {
void play(Note n) { print("Instrument.play() " + n); }
String what() { return "Instrument"; }
void adjust() { print("Adjusting Instrument"); }
}
class Wind extends Instrument {
void play(Note n) { print("Wind.play() " + n); }
String what() { return "Wind"; }
void adjust() { print("Adjusting Wind"); }
}
class Percussion extends Instrument {
void play(Note n) { print("Percussion.play() " + n); }
String what() { return "Percussion"; }
void adjust() { print("Adjusting Percussion"); }
}
class Stringed extends Instrument {
void play(Note n) { print("Stringed.play() " + n); }
String what() { return "Stringed"; }
void adjust() { print("Adjusting Stringed"); }
}
class Brass extends Wind {
void play(Note n) { print("Brass.play() " + n); }
void adjust() { print("Adjusting Brass"); }
}
class Woodwind extends Wind {
void play(Note n) { print("Woodwind.play() " + n); }
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);
}
}
基類Instrument 的方法都是“啞”方法,它這樣的設(shè)計(jì)的目的是所有導(dǎo)出類(子類)創(chuàng)建一個(gè)通用的接口(play,what,adjust)。
那么創(chuàng)建一個(gè)通用接口的理由是什么?
理由1:不同的子類可以用不同方式表示此接口。通用接口建立起一種基本形式,用來表示導(dǎo)出類的共同部分。
理由2:把Instrument (父類)搞成抽象類。我們創(chuàng)建抽象類的目的是通過通用接口操作一系列的類。
抽象類目的就是建立通用接口,一種通用基本形式,只有方法定義,沒有方法體實(shí)現(xiàn)。通俗講就是一種類型標(biāo)準(zhǔn)。
抽象類概念:包含抽象方法的類叫做抽象類。
抽象后的樂器關(guān)系圖

image.png
可以看出除了基類沒有任何變化。
抽象類是普通類和接口之間的一種中庸之道,抽象類有它的使用場(chǎng)景。譬如。部分接口實(shí)現(xiàn),部分接口定義為抽象方法,導(dǎo)出類直接集成就可以了。
抽象類帶來的好處是:更快的代碼開發(fā),更好的代碼組織,更好拓展程序及更容易的代碼維護(hù)。