一、外文资料译文:
译文标题
关键词:XXX,XXX,XXX,XXX
接口和抽象类提供了更结构化的方法来将接口与实现分离。
这种机制在编程语言中并不常见。例如,C++只对这些概念有间接支持。Java中存在语言关键字的事实表明,这些思想被认为足够重要,足以提供直接支持。首先,我们将研究抽象类,它是一种介于普通类和接口之间的中间步骤。虽然您的第一个冲动是创建接口,但是抽象类是构建具有一些未实现方法的类的重要和必要工具。你不能总是使用纯接口。
抽象类和方法
在前一章的所有“指令”示例中,基类指令中的方法都是“虚拟”方法。如果调用这些方法,您就做了一些错误。这是因为工具的目的是为从中派生的所有类创建一个公共接口。
在这些示例中,建立这个公共接口的唯一原因是,它可以针对每个不同的子类型不同地表达。它建立了一个基本的形式,这样您就可以说出所有派生类的常见内容。另一种说法是将工具称为抽象基类,或者简单地称为抽象类。
如果你有一个抽象类,比如工具,那么这个特定类的对象几乎总是没有意义的。当您希望通过一组类的公共接口操作一组类时,您将创建一个抽象类。因此,工具只表示接口,而不是特定的实现,因此创建工具对象没有意义,您可能希望阻止用户这样做。这可以通过使仪器中的所有方法产生错误来实现,但这会将信息延迟到运行时间,并且需要用户进行可靠的详尽测试。通常在编译时捕获问题更好。
Java提供了一种叫做抽象方法的机制。这是一个不完整的方法;它只有声明,没有方法主体。下面是抽象方法声明的语法。包含抽象方法的类称为抽象类。如果类包含一个或多个抽象方法,类本身必须被限定为抽象的。(否则,编译器会给您一条错误消息。)
如果抽象类不完整,那么编译器在试图创建该类的对象时应该怎么做?它无法安全地创建抽象类的对象,因此您可以从编译器中获得错误消息。这样,编译器确保抽象类的纯度,并且您不必担心滥用抽象类。
如果继承了抽象类,并且希望创建新类型的对象,则必须为基类中的所有抽象方法提供方法定义。如果您不这样做(并且您可能选择不这样做),那么派生类也是抽象的,编译器将强制您使用抽象关键字限定该类。
可以使用抽象类,而不包括任何抽象方法。当您有一个类,其中没有任何抽象方法是没有意义的,但是您希望阻止该类的任何实例时,这是很有用的。
上一章的类很容易变成抽象类。只有一些方法是抽象的,因为抽象类并不强迫您将所有方法抽象。
创建抽象类和方法很有帮助,因为它们使类的抽象性显式,并告诉用户和编译器它是如何被使用的。抽象类也是有用的重构toll,因为它们允许您轻松地将公共方法向继承层次结构移动。
接口
interface关键字将抽象的概念进一步提出来。abstract关键字允许您在提供接口部分的类中创建一个或多个未定义的方法,而不提供相应的实现。实现由继承者提供。interface关键字生成一个完全抽象的类,它根本不提供实现。它允许创建者确定方法名称、参数列表和返回类型,但不允许方法实体。接口只提供一个表单,但没有实现。
一个接口说,“实现这个特定接口的所有类都会这样。”因此,任何使用特定接口的代码都知道该接口可能调用什么方法,仅此而已。因此,接口用于在类之间建立一个“协议”。(一些面向对象编程语言有一个关键字protocol,用于做同样的事情。)
然而,接口不仅仅是一个抽象类,它允许您通过创建class来执行“多重继承”的变体您可以选择显式地将接口中的方法声明为public,但即使您不这样说,它们也是public的。因此,在实现接口时,必须将接口中的方法定义为public。否则,它们将默认为包访问,并且您将在继承期间减少方法的可访问性,这是Java编译器不允许的。
Java中的多重继承
因为一个接口根本没有实现,也就是说,没有与接口相关联的存储,所以没有什么可以阻止许多接口被合并。这是很有价值的,因为有时你需要说“a是一个a,一个b,一个c”。在C++中,这种组合多个类接口的行为被称为多重继承,并且它携带一些相当棘手的内容,因为每个类都有一个实现。在java中,可以执行相同的操作,但只有一个类可以实现,因此在组合多个接口时,C++不会出现java的问题。
在派生类中,您不必拥有抽象或“具体”的基类(没有抽象方法的)。如果确实从非接口继承,则可以从只有一个。所有其余的基本元素都必须是接口。你把所有的界面implements关键字后面的名称,并用逗号分隔。你可以有你想要多少接口就有多少。您可以向上投射到每个接口,因为每个接口都是一个独立类型。
在Adventure类中,您可以看到有四个方法接受各种接口和具体类。创建英雄对象时,可以传递它对于这些方法中的任何一个,这意味着它将依次向上投射到每个接口。因为在Java中设计接口的方式,这一点不需要用户特别的努力
程序员请记住,前面的示例中显示了接口的核心原因之一:
向上转换到多个基类型(以及它提供的灵活性)。然而,一个使用接口的第二个原因与使用抽象基类相同:防止客户机程序员从制作这个类的对象,并确定它只是一个接口。
这就提出了一个问题:您应该使用接口还是抽象类?如果可能的话创建没有任何方法定义或成员变量的基类时,应该总是喜欢接口而不是抽象类。事实上,如果你知道某件事将成为基类,您可以考虑将其作为一个接口。
扩展接口继承
您可以通过使用继承轻松地向接口添加新方法声明,并且您可以还将多个接口合并为一个新的接口和继承。在这两种情况下你都得到新接口。
DangerousMonster是Monster的一个简单扩展,它产生了一个新的接口。这个在DragonZilla中实现。吸血鬼中使用的语法只有在继承接口时才起作用。通常,你可以使用仅使用单个类进行扩展,但扩展可以在需要时引用多个基接口建立一个新的接口。如您所见,接口名称只是用逗号分隔。