抽象类和抽象方法的产生在Thinking in Java里面阐述的非常清楚了,正如那个Instrument的例子,Instrument类的对象没有任何意思,它是抽象的,定义在它里面的play()方法也是没有意思的,之所以定义这个方法,是为了在它的继承类中,可以用不同的方法类表示这个接口,产生不同的行为。为了防止客户端调用了这个方法,也不会产生编译错误,但是执行的结果不是客户端所希望的,那么怎样使得这样的调用在编译的时候就能发现问题,从而防止这种问题出现呢?解决的方法就是“抽象方法机制”。在方法前面加abstract关键词:
                                      abstract void f();
这个方法是不完整的,仅有申明没有方法体。那么就变成了抽象类,如果一个类包含一个或多个抽象方法,那么此类就必须限定为abstract的,否则编译器会报错。由于抽象类的不完整(抽象方法的不完整造成的)就不能产生该类的对象,编译器就会产生报错。

abstract class Instrument{
 public abstract void play();
}

class Wind extends Instrument{
  public void play(){
   System.out.println("Hello Wind!");
  }
}

public class Music{
 public static void tune(Instrument i){
  i.play();
 }
 
 public static void main(String[] args){
  Wind w = new Wind();
  tune(w);
 }
}

上面的输出结果为:
Hello Wind!

如果将Instrument的class前面abstract除掉就会产生编译错误:
Instrument 不是抽象的,并且未覆盖 Instrument 中的抽象方法 play()

当Music类中生成Instrument类时,看看编译能不能通过:

public class Music{
 public static void tune(Instrument i){
  i.play();
 }
 
 public static void main(String[] args){
  Wind w = new Wind();
  tune(w);
 }
}

结果编译报错:
Instrument 是抽象的;无法对其进行实例化

纵上可以得到,所谓“抽象”的引入是为了防止我们产生错误(或者说正确设计合适的类,没有实际意思的类可以将其“抽象”),而且为继承类提供统一接口。