也工作了很长时间了,可是一直搞不太懂接口和抽象类的区别和联系到底是怎么回事,面试的时候感觉好多公司都爱问这个问题,请大牛们给分析一下。

解决方案 »

  1.   

    窃以为:
    接口是can do something,是种契约,仅代表,实现它的类的实例,(除了出Exception的情况)一定能完成某(些)个任务。但是具体如何完成,你不知道,你也不需要知道也不应该关心抽象类是is something/has some properties。抽象类当然也能完成一些任务,但是,他除了完成这(些)个任务以外,还被强制规定死了,有些其他的属性,而且,很多时候,想换个方式完成这(些)个任务,因为已经在“体制内”,实在是很难很难。举个例子(下面说道的概念,仅在这个例子的范围内有效,换个应用,可能完全颠覆)
    “能飞的”是个接口,所有实现这个接口的类的实例,除了特例,都能飞起来
    public interface Flyable {
      public void fly();
    }而“鸟”这个概念,显然,除了能飞,还有些固定的属性,比如翅膀,喙什么的:public abstract class Bird // 上面还可能有Animal之类的父类,这里省略
      implements Flyable // 这里可能还有其他接口,比如“会吃东西”,“会叫”...
    {
      private Wing wings; // 翅膀
      private Beak beak; // 喙
      // 其他是鸟都会有的“属性”。当然有些属性,应当是在Animal这个层级的  public void fly() {
        wings.vibrate(); // 默认的实现方式,扇动翅膀
      }
      // 其他功能
    }public class Sparrow extends Bird {
      // 麻雀自己的一些特性
    }public abstract class WaterBird implements Swimmable {
      // 水禽都能游泳,在这里“能游泳”也是接口,而水禽成了“抽象类”
      // 水禽的一些特性
    }public class Swan extends WaterBird  {
      // 天鹅自己的一些特性
      public void fly() {
        if (water.getLength() < 100) {
          throw new FieldTooSmallException(); // 天鹅需要长距离助跑
        }
        runOnTheWater();
        wing.vibrate();
      }
    }// 少数的例外
    public class Ostrich extends Bird {
      public void fly() {
        throw new UnsupportedOperationException("鸵鸟不会飞!");
      }
    }
    回到Flyable这个接口,不是所有Flyable都是Bird,至少还有public abstract class Insect // 上面还可能有Animal之类的父类,这里省略
    implements Flyable // 这里可能还有其他接口,比如“会吃东西”,“会叫”...  private Wing wings; // 翅膀
      // 头胸腹,6条腿... 
    }
    // 蝙蝠是哺乳动物,哺乳动物不能飞,但是它能,刚好和鸵鸟相反
    public class Bat extends Mammal implements Flyable // 可能还有其他接口
    {
      // 蝙蝠的特性
      public void fly() {
        // 蝙蝠那个就不能叫翅膀了...
      }
    }public abstract class Aircraft implements Flyable // 可能还有其他父类、接口,比如是“机器”(类),“能加油”(接口)
    {
    ....
    }但愿上面的例子,能够让你在决定用接口还是抽象类的时候有所助益。
    实在想不明白,优先定义接口,用到其功能的地方,一律使用接口类型。然后,再提供一个通用的“抽象类”,提供一系列“模板方法”,实现这个接口的功能。
      

  2.   

    忘了一句。如果把刚才“能飞”这个概念,定义为抽象类Fly(不是苍蝇)你会发现,要实现我刚才说的那些,让这些东西,都出现在天上,几乎是不可能的。
      

  3.   

    接口比抽象类灵活,其实说白了就是java不支持多继承,用接口这种多实现的形式弥补了一下
      

  4.   

    这个好像是head first 设计模式中的 策略设计模式,多用组合,少用继承,用接口会更加灵活,不过还是哟啊具体问题具体分析了。
      

  5.   

    面向接口编程,比如java sql包下面很多是接口,它本身并不提供实现,而是由你的数据库去实现,你要回想用我的这个类,那么就必须按照我的定义来实现。简单说就是规范,这些都是一流公司做的哟。二流,三流公司只能跟在他们后面。
      

  6.   

    顶tank, 
    例子恰当+条理清晰。
    haha~~~
    time to close your post, OP.
      

  7.   


    接口是特殊的抽象类,详见我的日志:http://blog.csdn.net/fonyer/article/details/8961268