9.1 抽象类和抽象方法
Java提供一个抽象方法的机制,这种方法是不完整的;仅有声明而没有方法体。下面是抽象方法声明所采用的语法: abstract void f();
包含抽象方法的类叫做抽象类。如果一个类包含一个或多个抽象方法,该类必须被限定为抽象的。(否则编译器报错)。
如果从一个抽象类继承,并想创建新类的对象,那么就必须为基类中的所有抽象方法提供方法定义。如果不这样做,那么导出类便也是抽象类,且编译器会强制用abstract来限定这个类。
package thinkinjava.ch9.interfaces;
import thinkinjava.ch8.polymorphism.music.Note;
abstract class Instrument{
private int i;
public abstract void play(Note n);
public abstract void adjust();
public String what(){ return "Instrument";}
}
class Wind extends Instrument{
@Override
public void play(Note n) {
System.out.println("wind.play()"+n);
}
@Override
public void adjust() { }
@Override
public String what() {
return "wind";
}
}
class Percussion extends Instrument{
@Override
public void play(Note n) {
System.out.println("Percussion.play()"+n);
}
@Override
public void adjust() { }
@Override
public String what() {
return "Percussion";
}
}
class Stringed extends Instrument{
@Override
public void play(Note n) {
System.out.println("Stringed.play()"+n);
}
@Override
public void adjust() { }
@Override
public String what() {
return "Stringed";
}
}
class Brass extends Wind{
@Override
public void play(Note n) {
System.out.println("Brass.play()"+n);
}
@Override
public void adjust() { }
}
class Woodwond extends Wind{
@Override
public void play(Note n) {
System.out.println("Woodwind.play()"+n);
}
@Override
public String what() {
return "Woodwind";
}
}
public class Musics4 {
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) {
Instrument[] orchestra = {
new Wind(),
new Percussion(),
new Stringed(),
new Brass(),
new Woodwond()
};
tuneAll(orchestra);
}
}
运行结果:
wind.play()MIDDLE_C
Percussion.play()MIDDLE_C
Stringed.play()MIDDLE_C
Brass.play()MIDDLE_C
Woodwind.play()MIDDLE_C
除啦基类,实际上并没有什么改变。抽象类是重要的重构工具,使我们很容易将公共方法沿着继承层次结构向上移动。
9.2 接口
interface 关键字使抽象的概念更进一步。产生一个完全抽象的类,他根本没有提供任何具体实现。允许创建者确定方法名,参数列表和返回类型,但是没有任何方法体。接口只提供形式而未提供任何具体实现。
interface Instruments {
int i = 5;
void play(Note n); //Automatically public
void adjust();
}
class Winds implements Instruments{
@Override
public void play(Note n) {
System.out.println("winds.play()"+n);
}
@Override
public void adjust() {
System.out.println("winds.adjust()");
}
}
class Percussions implements Instruments{
@Override
public void play(Note n) {
System.out.println("Percussion.play()"+n);
}
@Override
public void adjust() {
System.out.println("Percession.adjust()");
}
}
class Stringeds implements Instruments{
@Override
public void play(Note n) {
System.out.println("Stringed.play()"+n);
}
@Override
public void adjust() {
System.out.println("Stringed.adjust()");
}
}
class Brasss extends Winds{
@Override
public void play(Note n) {
System.out.println("Brass.play()"+n);
}
@Override
public void adjust() {
System.out.println("Brass.adjust()");
}
}
class Woodwonds extends Winds{
@Override
public void play(Note n) {
System.out.println("Woodwind.play()"+n);
}
public void adjust() {
System.out.println("Woodwond.adjust()");
}
}
public class Music5 {
static void tune(Instruments i){
i.play(Note.MIDDLE_C);
}
static void tuneAll(Instruments[] e){
for (Instruments i:e) {
tune(i);
}
}
public static void main(String[] args) {
Instruments[] orchestra = {
new Winds(),
new Percussions(),
new Stringeds(),
new Brasss(),
new Woodwonds()
};
tuneAll(orchestra);
}
运行结果:
winds.play()MIDDLE_C
Percussion.play()MIDDLE_C
Stringed.play()MIDDLE_C
Brass.play()MIDDLE_C
Woodwind.play()MIDDLE_C
9.3 完全解耦
package thinkinjava.ch9.interfaces;
import java.util.Arrays;
public class Apply {
public static void process(Processor p, Object s){
System.out.println("using processor "+ p.name());
System.out.println(p.process(s));
}
public static String s = "daihfi hdahdaih hfudfh hfdauih";
public static void main(String[] args) {
process(new Upcase(),s);
process(new Downcase(),s);
process(new Splitter(),s);
}
}
class Processor{
public String name(){
return getClass().getSimpleName();
}
Object process(Object input) { return input;}
}
class Upcase extends Processor{
String process(Object input){
return ((String)input).toUpperCase();
}
}
class Downcase extends Processor{
String process(Object input){
return ((String)input).toLowerCase();
}
}
class Splitter extends Processor{
String process(Object input){
return Arrays.toString(((String)input).split(" "));
}
}
创建一个能够根据所传递的参数对象不同而具有不同行为的方法,被称为策略模式。策略就是传递进去的参对象,它包含要执行的代码。这里,Processor对象就是一策略,在main()中可以看到三种不同类型的策略应用到啦String类型的S对象上。