《Java编程思想》ch9.接口

接口

接口和内部类为我们提供了一种将接口与实现分离的更加结构化的方法。

9.1抽象类和抽象方法

  • 包含抽象方法的类叫做抽象类。如果一个类包含一个或多个抽象方法,该类必须被限定为抽象的。(否则,编译器就会报错。)
  • 如果从一个抽象类继承,并想创建该新类的对象,那么就必须为基类中的所有抽象方法提供方法定义。
  • 创建抽象类和抽象方法非常有用,因为它们可以使类的抽象性明确起来,并告诉用户和编译器打算怎样来使用它们。抽象类还是很有用的重构工具,因为它们使得我们可以很容易地将公共方法沿着继承层次结构向上移动。

9.2接口

  • interface这个关键字产生一个完全抽象的类。接口只提供了形式,而未提供任何具体实现。
  • 一个接口表示:所有实现了该特定接口的类看起来都像这样。
  • 接口被用来建立类与类之间的协议。
  • interface不仅是一个极度抽象的类,还可以实现某种类似多重继承的特性。
  • 接口可以包含域,但是这些域隐式地是static和final的。
  • 可以选择在接口中显式地将方法声明为public,但即使你不这么做,方法也是默认public。

9.3完全解耦

将接口从具体实现中解耦使得接口可以应用于多种不同的具体实现,因此代码也就更具可复用性。(通过方法操作的接口而非是类)

9.4Java中的多重继承

示例:

interface CanFight{
  void fight();
}
interface CanSwim{
  void swim();
}
interface canFly{
  void fly();
}
class ActionCharacter{
  public void fight() {}
}
class Hero extends ActionCharacter implements CanFight, CanSwim, CanFly{
  public swim() {}
  public fly() {}
}

使用接口的核心原因:为了能够向上转型为多个基类型(以及由此带来的灵活性);防止客户端程序员创建该类的对象,并确保这仅仅是建立一个接口。

9.5通过继承来扩展接口

通过继承,可以很容易地在接口中添加新的方法声明,还可以通过继承在新接口中组合数个接口。这两种情况都可以获得新的接口,示例:

interface Monster{
  void menace();
}
interface DangerousMonster extends Monster{
  void destroy();
}
interface Lethal{
  void kill();
}
interface Vampire extends DangerousMonster, Lethal{
  void drinkBlood();
}

另,在打算组合的不同接口中使用相同的方法名通常会造成代码可读性的混乱,请尽量避免这种情况。

9.6适配接口

接口的一种常见用法就是策略设计模式,此时编写一个执行某些操作的方法,而该方法将接受一个指定接口。主要就是要声明:你可以用任何你想要的对象来调用我的方法,只要你的对象遵循我的接口。

9.7接口中的域

接口中的任何域都自动是static和final的,所以接口就成为了一种很便捷的用来创建常量组的工具。
在接口中定义的域不能是“空final”,但是可以被非常量表达式初始化。

9.8嵌套接口

接口可以前套在类或其它接口中。
示例:

class A{
  interface B{
    void f();
  }
  public class BImp implements B{
    public void f(){}
  }
  private class BImp2 implements B{
    public void f(){}
  }

  public interface C{
    void f();
  }
  class CImp implements C{
    public void f(){}
  }
  private class CImp2 implements C{
    public void f(){}
  }

  private interface D{
    void f();
  }
  private class DImp implements D{
    public void f(){}
  }
  public class DImp2 implements D{
    public void f(){}
  }

  public D getD() {return new DImp2();}
  private D dRef;
  public void receiveD(D d){
    dRef=d;
    dRef.f();
  }
}
interface E{
  interface G{
    void f();
  }
  public interface H{
    void f();
  } //此处public是redundant
  void g();
  //! private interface I {}
  // 接口内不能有私有接口
}
public class NestingInterfaces {
  public class BImpl implements A.B {
    public void f(){}
  }
  public class CImpl implements A.C{
    public void f(){}
  }
  //不能实现私有接口,除非在该私有接口的定义类中
  // ! class DImpl implements A.D{ public void f(){}}
  class EImpl implements E{
    public void g(){}
  }
  class EGImp implements E.G{
    public void f(){}
  }
  class EImp2 implements E{
    public void g(){}
    class EG implements E.G{
      public void f(){}
    }
  }
  public static void main(String[] args){
    A a = new A();
    //! A.D ad = a.getD();
    //! A.Dimp2 di2 = a.getD();
    //! a.getD().f();
    //only another A can do anything with getD()
    A a2 = new A();
    a2.receiveD(a.getD());
  }
}

说明:getD()方法是一个对private接口引用进行返回的public方法,只有一种方式可以使用:那就是将返回值交给有权使用它的对象。
接口E说明接口彼此之间也可以嵌套,所有接口元素必须是public。实现一个接口时,并不需要实现它内部的接口。而且私有接口不能在定义它的类的外部被实现。

9.9接口与工厂

工厂方法设计模式

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容