The Java Tutorials have been written for JDK 8.Java教程是为JDK 8编写的。Examples and practices described in this page don't take advantage of improvements introduced in later releases and might use technology no longer available.本页中描述的示例和实践没有利用后续版本中引入的改进,并且可能使用不再可用的技术。See Java Language Changes for a summary of updated language features in Java SE 9 and subsequent releases.有关Java SE 9及其后续版本中更新的语言特性的摘要,请参阅Java语言更改。
See JDK Release Notes for information about new features, enhancements, and removed or deprecated options for all JDK releases.有关所有JDK版本的新功能、增强功能以及已删除或不推荐的选项的信息,请参阅JDK发行说明。
An abstract class is a class that is declared 抽象类是声明为abstract
it may or may not include abstract methods. abstract
的类它可能包括也可能不包括抽象方法。Abstract classes cannot be instantiated, but they can be subclassed.抽象类不能实例化,但可以子类化。
An abstract method is a method that is declared without an implementation (without braces, and followed by a semicolon), like this:抽象方法是在没有实现的情况下声明的方法(不带大括号,后跟分号),如下所示:
abstract void moveTo(double deltaX, double deltaY);
If a class includes abstract methods, then the class itself must be declared 如果类包含抽象方法,则必须将该类本身声明为abstract
, as in:abstract
,如中所示:
public abstract class GraphicObject { // declare fields // declare nonabstract methods abstract void draw(); }
When an abstract class is subclassed, the subclass usually provides implementations for all of the abstract methods in its parent class. 当抽象类被子类化时,子类通常为其父类中的所有抽象方法提供实现。However, if it does not, then the subclass must also be declared 但是,如果没有,那么子类也必须声明为abstract
.abstract
。
abstract
modifier is not used with interface methods. Abstract classes are similar to interfaces. 抽象类类似于接口。You cannot instantiate them, and they may contain a mix of methods declared with or without an implementation. 您不能实例化它们,它们可能包含使用或不使用实现声明的方法的混合。However, with abstract classes, you can declare fields that are not static and final, and define public, protected, and private concrete methods. 但是,对于抽象类,您可以声明非静态和最终的字段,并定义公共、受保护和私有的具体方法。With interfaces, all fields are automatically public, static, and final, and all methods that you declare or define (as default methods) are public. 对于接口,所有字段都自动是公共的、静态的和最终的,并且您声明或定义的所有方法(作为默认方法)都是公共的。In addition, you can extend only one class, whether or not it is abstract, whereas you can implement any number of interfaces.此外,您只能扩展一个类,不管它是否抽象,而您可以实现任意数量的接口。
Which should you use, abstract classes or interfaces?您应该使用哪一种,抽象类还是接口?
Comparable
and Cloneable
are implemented by many unrelated classes.Comparable
接口和Cloneable
接口由许多不相关的类实现。An example of an abstract class in the JDK is JDK中抽象类的一个例子是AbstractMap
, which is part of the Collections Framework. AbstractMap
,它是集合框架的一部分。Its subclasses (which include 它的子类(包括HashMap
, TreeMap
, and ConcurrentHashMap
) share many methods (including get
, put
, isEmpty
, containsKey
, and containsValue
) that AbstractMap
defines.HashMap
、TreeMap
和ConcurrentHashMap
)共享AbstractMap
定义的许多方法(包括get
、put
、isEmpty
、containsKey
和containsValue
)。
An example of a class in the JDK that implements several interfaces is JDK中实现多个接口的类的一个示例是HashMap
, which implements the interfaces Serializable
, Cloneable
, and Map<K, V>
. HashMap
,它实现了Serializable
接口、Cloneable
接口和Map<K, V>
接口。By reading this list of interfaces, you can infer that an instance of 通过阅读此接口列表,可以推断HashMap
(regardless of the developer or company who implemented the class) can be cloned, is serializable (which means that it can be converted into a byte stream; see the section Serializable Objects), and has the functionality of a map. HashMap
的实例(无论实现该类的开发人员或公司是谁)可以克隆,是可序列化的(这意味着它可以转换为字节流;请参阅可序列化对象一节),它还具有映射的功能。In addition, the 此外,Map<K, V>
interface has been enhanced with many default methods such as merge
and forEach
that older classes that have implemented this interface do not have to define.Map<K, V>
接口已通过许多默认方法(如merge
和forEach
)得到了增强,实现此接口的旧类不必定义这些方法。
Note that many software libraries use both abstract classes and interfaces; the 注意,许多软件库同时使用抽象类和接口;HashMap
class implements several interfaces and also extends the abstract class AbstractMap
.HashMap
类实现了几个接口,还扩展了抽象类AbstractMap
。
In an object-oriented drawing application, you can draw circles, rectangles, lines, Bezier curves, and many other graphic objects. 在面向对象的绘图应用程序中,可以绘制圆、矩形、直线、贝塞尔曲线和许多其他图形对象。These objects all have certain states (for example: position, orientation, line color, fill color) and behaviors (for example: moveTo, rotate, resize, draw) in common. 这些对象都具有某些共同的状态(例如:位置、方向、线颜色、填充颜色)和行为(例如:移动到、旋转、调整大小、绘制)。Some of these states and behaviors are the same for all graphic objects (for example: position, fill color, and moveTo). 其中一些状态和行为对于所有图形对象都是相同的(例如:位置、填充颜色和移动到)。Others require different implementations (for example, resize or draw). 其他需要不同的实现(例如,调整大小或绘制)。All 所有GraphicObject
s must be able to draw or resize themselves; they just differ in how they do it. GraphicObject
必须能够绘制或调整自身大小;他们只是在做这件事的方式上有所不同。This is a perfect situation for an abstract superclass. 对于抽象超类来说,这是一个完美的情况。You can take advantage of the similarities and declare all the graphic objects to inherit from the same abstract parent object (for example, 您可以利用相似性并声明所有图形对象从同一抽象父对象(例如GraphicObject
) as shown in the following figure.GraphicObject
)继承,如下图所示。
Classes Rectangle, Line, Bezier, and Circle Inherit from GraphicObject类矩形、直线、贝塞尔和圆继承自GraphicObject
First, you declare an abstract class, 首先,声明一个抽象类GraphicObject
, to provide member variables and methods that are wholly shared by all subclasses, such as the current position and the moveTo
method. GraphicObject
,以提供所有子类完全共享的成员变量和方法(如当前位置和moveTo
方法)。GraphicObject
also declares abstract methods for methods, such as draw
or resize
, that need to be implemented by all subclasses but must be implemented in different ways. GraphicObject
还为需要由所有子类实现但必须以不同方式实现的方法(如draw
或resize
)声明抽象方法。The GraphicObject
class can look something like this:GraphicObject
类可以如下所示:
abstract class GraphicObject { int x, y; ... void moveTo(int newX, int newY) { ... } abstract void draw(); abstract void resize(); }
Each nonabstract subclass of GraphicObject
, such as Circle
and Rectangle
, must provide implementations for the draw
and resize
methods:GraphicObject
的每个非抽象子类(如Circle
和Rectangle
)必须提供draw
方法和resize
方法的实现:
class Circle extends GraphicObject { void draw() { ... } void resize() { ... } } class Rectangle extends GraphicObject { void draw() { ... } void resize() { ... } }
In the section on 在接口一节中,注意到实现接口的类必须实现接口的所有方法。Interfaces
, it was noted that a class that implements an interface must implement all of the interface's methods. It is possible, however, to define a class that does not implement all of the interface's methods, provided that the class is declared to be 但是,如果类被声明为abstract
. abstract
类,则可以定义一个不实现所有接口方法的类。For example,
abstract class X implements Y { // implements all but one method of Y } class XX extends X { // implements the remaining method in Y }
In this case, class 在这种情况下,类X
must be abstract
because it does not fully implement Y
, but class XX
does, in fact, implement Y
.X
必须是abstract
,因为它没有完全实现Y
,但类XX
实际上实现了Y
。
An abstract class may have 抽象类可以有静态字段和静态方法。static
fields and static
methods. You can use these static members with a class reference (for example, 您可以将这些静态成员与类引用(例如AbstractClass.staticMethod()
) as you would with any other class.AbstractClass.staticMethod()
)一起使用,就像与任何其他类一起使用一样。