接口
为什么需要接口
一方面,有时必须从几个类中派生出一个子类,继承它们所有的属性和方法。但是,Java 不支持多重继承。有了接口,就可以得到多重继承的效果。
另一方面,有时必须从几个类中抽取出一些共同的行为特征,而它们之间又没有 is-a 的关系,仅仅是具有相同的行为特征而已。如:鼠标、键盘、打印机等都支持 USB 连接。
接口就是规范,定义的是一组规则。继承实现的是是不是的逻辑,而接口定义的是能不能的逻辑。
注意点
接口是抽象方法和常量定义的集合:
- 接口中所有的成员变量默认都是 public static final 修饰的。
- 接口中所有抽象方法默认都是 public abstract 修饰的。
- 接口中没有构造器。
- 接口与接口之间可以多继承。
- 与继承关系类似,接口与实现类之间存在多态性。
1 2 3
| class SubClass extends SuperClass implements InterfaceA, InterfaceB{ }
|
JDK 7.0 及以前,接口中只能定义常量和抽象方法。
JDK 8.0 开始,接口中除了定义常量和抽象方法之外,还可以定义静态方法、默认方法。
- 接口中定义的静态方法,只能通过接口来调用。
- 通过实现接口的对象,可以调用接口的默认方法。
- 如果子类继承的父类和实现的接口中,定义了同名同参数的(默认)方法,在没有重写的情况下,默认调用父类中的方法(类优先原则)。
- 在实现类中调用被重写的默认方法:
1 2
| InterfaceA.super.method(); InterfaceB.super.method();
|
接口的多态性
接口的多态性体现如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| class Computer { public void work(USB usb) { usb.start(); usb.stop(); } }
interface USB { void start(); void stop(); }
class Mouse implements USB { public void start() { } public void stop() { } }
class Printer implements USB { public void start() { } public void stop() { } }
|
接口应用 - 代理设计模式
代理设计就是为其他对象提供一种代理以控制对这个对象的访问。
分为:
- 静态代理:静态定义代理类。
- 动态代理:动态生成代理类。
静态代理
静态代理中包括代理类和被代理类。
- 被代理类用于实现核心功能。
- 代理类用于实现,控制被代理类的访问。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| interface Network { public void browse(); }
class RealServer implements Network { @Override public void browse() { System.out.println("真实服务器上网浏览信息"); } }
class ProxyServer implements Network { private Network network; public ProxyServer(Network network) { this.network = network; } public void check() { System.out.println("检查网络连接等操作"); } public void browse() { check(); network.browse(); } }
|
接口应用 - 工厂设计模式
工厂模式:实现了创建者与调用者的分离,将创建对象的具体过程屏蔽起来,达到高灵活性的目的。
工厂模式的分类:
简单工厂模式
简单工厂模式定义一个用于创建对象的工厂类。
调用者只要知道他要什么,从哪里拿、如何创建不需要知道。
缺点:对于增加新产品,不修改代码的话,是无法扩展的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| interface Car { void run(); }
class Audi implements Car { public void run() { System.out.println("奥迪在跑"); } }
class BYD implements Car { public void run() { System.out.println("比亚迪在跑"); } }
class CarFactory { public static Car getCar(String type) { if ("奥迪".equals(type)) { return new Audi(); } else if ("比亚迪".equals(type)) { return new BYD(); } else { return null; } } }
|
工厂方法模式
工厂方法模式有一组实现了相同接口的工厂类。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| interface Car{ void run(); }
class Audi implements Car { public void run() { System.out.println("奥迪在跑"); } }
class BYD implements Car { public void run() { System.out.println("比亚迪在跑"); } }
interface Factory{ Car getCar(); }
class AudiFactory implements Factory{ public Audi getCar(){ return new Audi(); } }
class BydFactory implements Factory{ public BYD getCar(){ return new BYD(); } }
|
接口与抽象类的对比
内部类
在 Java 中,允许一个类的定义位于另一个类的内部,前者称为内部类,后者称为外部类。