接口
接口和内部类为我们提供了一种将接口和实现分离的更加结构化的方法。
一、抽象类和抽象方法
抽象类是普通类和接口之间的一种中庸之道。尽管在构建具有某些未实现方法的类时,你的第一想法可能是创建接口,但是抽象类仍旧是用于此目的的一种重要而必须的工具。因为你不可能总是使用纯接口。
java提供抽象方法机制,仅有声明没有方法体。用abstract修饰。包含抽象方法的类叫抽象类。如果一个类包含一个或多个抽象方法,该类必须被限定为抽象的(否则编译器报错)。由于未抽象类创建对象是不安全的,所以我们会从编译时期哪里得到一条出错的消息。这样编译器会确保抽象类的纯粹性,我们不必担心误用它。
如果从一个抽象类继承,并想创建该新类的对象,那么就必须为基类中的所有抽象方法提供方法定义。如果不这样做(可以不做),那么导出类也是抽象类,且编译器会强制使用abstract关键字来限定这个类。
创建抽象类和抽象方法非常有用,因为他们可以使类的抽象性明确起来,并告诉编译器打算怎么样来使用它们。抽象类还是很有用的重构工具,因为它们使得我们可以很容易地将公共方法沿着继承层次结构向上移动。
二、接口
interface这个关键字产生一个完全抽象的类,它根本没有提供任何具体实现。它允许创建者确定方法名,参数列表和返回类型,但是没有任何方法体。接口只提供了形式,而未提供任何具体实现。
接口被用来建立类与类之间的协议。interface不仅仅是一个极度抽象的类,因为它允许人们通过创建一个能够被向上转型为多种基类的类型,来实现 某种类似多重继变种的特性。
接口也可以包含域,但是这些域隐式地是static和final的。要让某个类遵循某个特定接口,需要使用implements关键字,表示interface只是外貌,但是现在我要声明它是如何工作的。
三、完全解耦
创建一个能够根据所传递的参数对象的不同而具有不同行为的方法,被称为策略设计模式。这类方法包含所要执行的算法中固定不变的部分,而策略包含变化的部分。策略就是传递进去的参数对象,它包含要执行的代码。
适配器设计模式--适配器中的代码将接受你所拥有的接口,并产生你所需要的接口。
将接口从具体实现中解耦使得接口可以应用于多种不同的具体实现,因此代码也就更具复用性。
四、java中的多重继承
接口是根本没有任何具体实现的--也就是说,没有任何与接口相关的存储,因此无法阻止多个接口的组合。
在导出类中,不强制要求必须由一个是抽象的或具体的(没有任何抽象方法)基类。如果要从一个非接口的类继承,只能从一个类去继承,其余的基元素都必须是接口。需要将所有的接口名都置于implements关键字后,用逗号将它们一一隔开。可以继承任意多个接口,并可以向上转型为每个接口,因为每一个接口都是一个独立类型。
使用接口的核心原因:为了能够向上转型为多个基类型(以及由此而带来的灵活性)。防止客户端程序员创建该类对象,并确保仅是建立一个接口。
五、通过继承来扩展接口
通过继承可以很容易在接口中添加新的方法声明,还可以通过继承在新接口中组合数个接口。
一般情况下,只可以将extends用于单一类,但是可以引用多个基类接口,只需将接口名一一分开即可。
在打算组合的不同接口中使用相同的方法名通常会造成代码可读性的混乱,请尽量避免这种情况。
六、适配接口
接口最吸引人的原因之一就是允许同一个接口具有多个不同的具体实现。
接口的一种常见用法就是提到的策略模式:你可以用任何你想要的的对象来调用我的方法,只要你的对象遵循我的接口,这使得你的方法更加灵活,通用,更具可复用性。
七、接口中的域
放入接口中的任何域都自动是static和final的,所以接口就称为了一种很便捷的用来创建常量组的工具。接口中的域自动是public的,所以没有显式地指明这一点。
八、嵌套接口
接口可以嵌套在类或者其他接口中。
当实现某个接口时,并不需要实现嵌套在其内部的任何接口。
九、接口与工厂
接口是实现多重继承的途径,而生产遵循某个接口的对象的典型方式就是工厂设计模式。通过这种方式,代码完全与接口的实现分离,这就使得我们可以透明地将某个实现替换为另一个实现。
十、总结
任何抽象性都应该是应真正的需求而产生的。当必需时,你应该重构接口而不是到处添加额外级别的间接性,并由此带来的额外的复杂性。
恰当的原则应该是优先选择类而不是接口。从类开始,如果接口的必需性变得非常明确,那么就进行重构。接口是一种重要工具,但他们容易被滥用。