在所有“乐器”的例子中,Instrument类的目的是为它的所有导出类创建一个通用接口。建立通用接口的唯一理由:不同的子类可以用不同的方式表示此接口。通用接口建立起一种基本形式,以此表示所有导出类的共同部分。当希望通过通用接口操纵一系列类时,就需创建一个抽象类。与基类所声明的特征签名相符(重载不相符,因为特征标签中的参数不同)的所有导出类方法,都会通过动态绑定机制来调用。
如果我们只有一个像Instrument这样的抽象类,那么该类的对象几乎没有任何意义。Instrument只是表示了一个接口,没有具体的实现内容;因此创建一个Instrument对象没有什么意义,并且我们可能还想阻止使用者这样做。
为此,Java提供了一个“抽象方法”的机制,这种方法是不完整的:仅有声明而没有方法体(即抽象方法没有符号:{})。eg:abstract void f();
包含抽象方法的类叫做“抽象类”。如果一个类包含一个或多个抽象方法,该类必须被限定为抽象的(否则编译器会报错)。同样,编译器会确保抽象类的纯粹性,我们不必担心会误用它(为抽象类创建对象时会报错)。
**如果从一个抽象类继承,并想创建该新类的对象,那么就必须为基类中的所有抽象方法提供方法定义。如果不这样做(当然可以不这么做),那么导出类便也是抽象类,且编译器将会强制我们用abstract关键字来限定这个类。
Instrument类很容易转化为abstract类。既然使某个类称为抽象类并不需要所有的方法都是抽象的,所以仅需将某些方法声明为抽象的即可。
* Title: Abstract classes and methods<br>
* Description: 此例解释"抽象类和抽象方法"概念, 无任何功能接口<br>
* Company: Augmentum Inc<br>
* Copyright: (c) 2008 Thinking in Java<br>
* @author Forest He
* @version 1.0
*/
package com.augmentum.foresthe;
class Note ... {
private String noteName;
private Note (String noteName)...{ this.noteName = noteName; }
public String toString() ...{ return noteName; }
public static final Note
MIDDLE_C = new Note("MIDDLE_C"),
C_SHARP = new Note("C_SHARP"),
B_FLAT = new Note("B_FLAT");
}
abstract class Instrument ... {
public abstract void play(Note note);
public String what() ...{ return "Instrument"; }
public abstract void adjust();
}
class Wind extends Instrument ... {
public void play(Note note) ...{ System.out.println("Wind.play() " + note.toString()); }
public String what() ...{ return "Wind"; }
public void adjust() ...{};
}
class Percussion extends Instrument ... {
public void play(Note note) ...{ System.out.println("Percussion.play() " + note.toString()); }
public String what() ...{ return "Percussion"; }
public void adjust() ...{};
}
class Stringed extends Instrument ... {
public void play(Note note) ...{ System.out.println("Stringed.play() " + note.toString()); }
public String what() ...{ return "Stringed"; }
public void adjust() ...{};
}
class Brass extends Wind ... {
public void play(Note note) ...{ System.out.println("Brass.play() " + note.toString()); }
public void adjust() ...{ System.out.println("Brass.adjust()"); }
}
class Woodwind extends Wind ... {
public void play(Note note) ...{ System.out.println("Woodwind.play() " + note.toString()); }
public String what() ...{ return "Woodwind"; }
}
public class Music ... {
public static void tune(Instrument i) ...{ i.play(Note.C_SHARP); }
public static void tuneAll(Instrument[] e) ...{
for(int i = 0; i < e.length; i++) tune(e[i]);
}
public static void main(String[] args) ...{
Instrument[] orchestra = ...{
new Wind(), new Percussion(), new Stringed(), new Brass(), new Woodwind()
};
tuneAll(orchestra);
}
}