接口

抽象类,是普通的类与接口之间的一种中庸之道。

抽象类和抽象方法

Java提供一个叫做抽象方法的机制,这种方法是不完整的;仅有声明而没有方法体。

abstract void f();

包含抽象方法的类叫做抽象类。如果一个类包含一个或多个抽象方法,该类必须被限定为抽象的。

如果一个抽象类继承,并想创建该新类的对象,那么就必须为基类中的所有抽象方法提供方法定义。如果不这样做,那么导出类也是抽象类,并且必须用abstract关键字来限定这个类。

可以声明一个没有抽象方法的类为抽象类,这样可以阻止产生这个类的任何对象。

抽象类和抽象方法,可以使类的抽象性明确起来。抽象类还有很有用的重构工具,因为它们使得我们可以很容易地将公共方法沿着继承层次结构向上移动。

接口

interface这个关键字产生一个完全抽象的类,它根本就没有提供任何具体实现。它允许创建者确定方法名、参数列表和返回类型,但是没有任何方法体。接口只提供了形式,而未提供任何具体实现。

interface不仅是一个极度抽象的类,因为它允许人们通过创建一个能够被向上转型为多种基类的类型,来实现某种类似多重继承变种的特性。

要想创建一个接口,需要用interface关键字来替代class关键字。就像类一样,关键字前添加public关键字。如果不添加public,默认为包访问权限。

接口也可以包含域,但是这些域隐式地是static和final的。

要让一个类遵循某个特定接口或者是一组接口,需要使用implements关键字。

接口中的方法必须是public的。可以选择在接口中显式地将方法生命为public的,但即使你不这么做,它们也是public的。

完全解耦

只要一个方法操作的是类而非接口,那么你就只能使用这个类及其子类。接口可以在很大程度上放宽这种限制,它使得我们可以编写可复用性更好的代码。

将接口从具体实现中解耦使得接口可以应用于多种不同的具体实现,因此代码也就更具可复用性。

Java中的多重继承

Java中只能从一个类继承,其余的元素都必须是接口。需要将所有的接口名都置于implements关键字之后,用逗号将它们一一隔开。可以继承任意多个接口,并可以向上转型为每个接口,因为每一个接口都是一个独立类型。

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

应该使用接口还是抽象类?如果要创建不带任何方法定义和成员变量的基类,那么就应该选择接口而不是抽象类。

通过继承来扩展接口

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

一般情况下,只可以将extends用于单一类,但是可以引用多个基类接口。

组合接口时的名字冲突

适配接口

Java允许同一个接口具有多个不同的具体实现,体现形式通常是一个接受接口类型的方法,而该接口的实现和向该方法传递的对象则取决于方法的使用者。

可以在任何现有类之上添加新的接口,所以这意味着让方法接受接口类型,是一种任何类都可以对该方法进行适配的方式。

接口中的域

接口中的域默认是public、static、final的,所以接口就成为一种很便捷的方式来创建常量组。这与Java SE5及之后的enum类型作用相似。

初始化接口中的域

在接口中定义的域不能是“空final”,但是可以被非常量表达式初始化。

域是static的,它们就可以在类第一次被加载时初始化,这发生在任何域被首次访问之前。

这些域不是借口的一部分,它们的值被存储在该接口的静态存储区域内。

嵌套接口

接口可以嵌套在类或其他接口中。

嵌套在另一个接口中的接口自动就是public。

当实现一个接口时,并不需要实现嵌套在其内部的接口。

接口与工厂

最后更新于