法都是抽象的,所以仅需将某些方法声明为抽象的即可。
下面是修改过的“管弦乐队”的例子,其中采用了抽象类和抽象方法:
//: c07:music4:Music4.java
// Abstract classes and methods.
package c07.music4;
import com.bruceeckel.simpletest.*;
import java.util.*;
import c07.music.Note;
abstract class Instrument {
private int i; // Storage allocated for each
public abstract void play(Note n);
public String what() {
return "Instrument";
}
public abstract void adjust();
}
class Wind extends Instrument {
public void play(Note n) {
System.out.println("Wind.play() " + n);
}
public String what() { return "Wind"; }
public void adjust() {}
}
class Percussion extends Instrument {
public void play(Note n) {
System.out.println("Percussion.play() " + n);
}
public String what() { return "Percussion"; }
public void adjust() {}
}
class Stringed extends Instrument {
public void play(Note n) {
System.out.println("Stringed.play() " + n);
}
public String what() { return "Stringed"; }
public void adjust() {}
}
class Brass extends Wind {
public void play(Note n) {
System.out.println("Brass.play() " + n);
}
public void adjust() {
System.out.println("Brass.adjust()");
}
}
class Woodwind extends Wind {
public void play(Note n) {
System.out.println("Woodwind.play() " + n);
}
public String what() { return "Woodwind"; }
}
public class Music4 {
private static Test monitor = new Test();
// 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(int i = 0; i < e.length; i++)
tune(e[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);
monitor.expect(new String[] {
"Wind.play() Middle C",
"Percussion.play() Middle C",
"Stringed.play() Middle C",
"Brass.play() Middle C",
"Woodwind.play() Middle C"
});
}
} ///:~
我们可以看出,除了基类,实际上并没有什么改变。
创建抽象类和抽象方法非常有用,因为它们可以显化一个类的抽象性,并告诉用户和编译器
怎样按照它所预期的方式来使用。