ClassDeclaration:If a class is declared in a named package with fully qualified name P, then the class has the fully qualified name P
ClassModifiersoptclass
IdentifierSuperopt
Interfacesopt
ClassBody
.
Identifier. If the class is in an
unnamed package, then the class has the fully qualified name Identifier.
In the example:
class Point { int x, y; }the class
Point
is declared in a compilation unit with no package
statement, and
thus Point
is its fully qualified name, whereas in the example:
package vista; class Point { int x, y; }the fully qualified name of the class
Point
is vista.Point
. (The package name
vista
is suitable for local or personal use; if the package were intended to be
widely distributed, it would be better to give it a unique package name.)
A compile-time error occurs if the Identifier naming a class appears as the name of any other class type or interface type declared in the same package.
A compile-time error occurs if the Identifier naming a class is also declared as a type by a single-type-import declaration in the compilation unit containing the class declaration.
package test;the first compile-time error is caused by the duplicate declaration of the name
import java.util.Vector;
class Point { int x, y; }
interface Point { // compile-time error #1 int getR(); int getTheta(); }
class Vector { Point[] pts; } // compile-time error #2
Point
as both a class
and an interface
in the same package. A second error
detected at compile time is the attempt to declare the name Vector
both by a class
type declaration and by a single-type-import declaration.
Note, however, that it is not an error for the Identifier that names a class also to name a type that otherwise might be imported by a type-import-on-demand declaration in the compilation unit containing the class declaration. In the example:
package test;the declaration of the class
import java.util.*;
class Vector { Point[] pts; } // not a compile-time error
Vector
is permitted even though there is also a class
java.util.Vector
. Within this compilation unit, the simple name Vector
refers
to the class test.Vector
, not to java.util.Vector
(which can still be referred
to by code within the compilation unit, but only by its fully qualified name).
package points;
class Point { int x, y; // coordinates PointColor color; // color of this point Point next; // next point with this colordefines two classes that use each other in the declarations of their class members. Because the class type names
static int nPoints; }
class PointColor { Point first; // first point with this color PointColor(int color) { this.color = color; } private int color; // color components }
Point
and PointColor
have the entire package
points
, including the entire current compilation unit, as their scope, this example
compiles correctly-that is, forward reference is not a problem.
ClassModifiers:A compile-time error occurs if the same modifier appears more than once in a class declaration. If two or more class modifiers appear in a class declaration, then it is customary, though not required, that they appear in the order consistent with that shown above in the production for ClassModifier.
ClassModifier
ClassModifiersClassModifier ClassModifier: one of
public
abstract final
abstract
class is a class that is incomplete, or to be considered incomplete.
Only abstract
classes may have abstract
methods, that is,
methods that are declared but not yet implemented. If a class that is not abstract
contains an abstract
method, then a compile-time error occurs. A class has
abstract
methods if any of the following is true:
abstract
method.
abstract
method from its direct superclass.
abstract
) and the class neither declares nor inherits a method that implements it.
abstract class Point { int x = 1, y = 1; void move(int dx, int dy) { x += dx; y += dy; alert(); } abstract void alert(); }a class
abstract class ColoredPoint extends Point { int color; }
class SimplePoint extends Point { void alert() { } }
Point
is declared that must be declared abstract
, because it contains a
declaration of an abstract
method named alert
. The subclass of Point
named
ColoredPoint
inherits the abstract
method alert
, so it must also be declared
abstract
. On the other hand, the subclass of Point
named SimplePoint
provides an implementation of alert
, so it need not be abstract
.
A compile-time error occurs if an attempt is made to create an instance of an abstract
class using a class instance creation expression. An attempt to instantiate an abstract
class using the newInstance
method of class Class
will cause an InstantiationException
to be thrown. Thus, continuing the example just shown, the statement:
Point p = new Point();would result in a compile-time error; the class
Point
cannot be instantiated
because it is abstract
. However, a Point
variable could correctly be initialized
with a reference to any subclass of Point
, and the class SimplePoint
is not
abstract
, so the statement:
Point p = new SimplePoint();would be correct.
A subclass of an abstract
class that is not itself abstract
may be instantiated, resulting in the execution of a constructor for the abstract
class and, therefore, the execution of the field initializers for instance variables of that class. Thus, in the example just given, instantiation of a SimplePoint
causes the default constructor and field initializers for x
and y
of Point
to be executed.
It is a compile-time error to declare an abstract
class type such that it is not possible to create a subclass that implements all of its abstract
methods. This situation can occur if the class would have as members two abstract
methods that have the same method signature but different return types. As an example, the declarations:
interface Colorable { void setColor(int color); } abstract class Colored implements Colorable { abstract int setColor(int color); }result in a compile-time error: it would be impossible for any subclass of class
Colored
to provide an implementation of a method named setColor
, taking one
argument of type int
, that can satisfy both abstract
method specifications,
because the one in interface Colorable
requires the same method to return no
value, while the one in class Colored
requires the same method to return a value
of type int
.
A class type should be declared abstract
only if the intent is that subclasses can be created to complete the implementation. If the intent is simply to prevent instantiation of a class, the proper way to express this is to declare a constructor of no arguments, make it private
, never invoke it, and declare no other constructors. A class of this form usually contains class methods and variables. The class java.lang.Math
is an example of a class that cannot be instantiated; its declaration looks like this:
public final class Math {
private Math() { } // never instantiate this class
. . . declarations of class variables and methods . . .
}
final
if its definition is complete and no subclasses are
desired or required. A compile-time error occurs if the name of a final
class
appears in the extends
clause of another class
declaration; this implies
that a final
class cannot have any subclasses. A compile-time error occurs if a
class is declared both final
and abstract
, because the implementation of such a
class could never be completed.
Because a final
class never has any subclasses, the methods of a final
class are never overridden.
extends
clause in a class declaration specifies the direct superclass
of the current class. A class is said to be a direct subclass of the class it extends.
The direct superclass is the class from whose implementation the implementation
of the current class is derived. The extends
clause must not appear in the definition of the class java.lang.Object
, because it is the primordial class
and has no direct superclass. If the class declaration for any other class has no
extends
clause, then the class has the class java.lang.Object
as its implicit
direct superclass.
Super:The following is repeated from to make the presentation here clearer:
extends
ClassType
ClassType:The ClassType must name an accessible class type, or a compile-time error occurs. All classes in the current package are accessible. Classes in other packages are accessible if the host system permits access to the package and the class is declared
TypeName
public
. If the specified ClassType names a class that is final
, then a compile-time error occurs; final
classes are not allowed to have subclasses.
the relationships are as follows:
class Point { int x, y; }
final class ColoredPoint extends Point { int color; }
class Colored3DPoint extends ColoredPoint { int z; } // error
Point
is a direct subclass of java.lang.Object
.
java.lang.Object
is the direct superclass of the class Point
.
ColoredPoint
is a direct subclass of class Point
.
Point
is the direct superclass of class ColoredPoint
.
Colored3dPoint
causes a compile-time error because it
attempts to extend the final
class ColoredPoint
.
The subclass relationship is the transitive closure of the direct subclass relationship. A class A is a subclass of class C if either of the following is true:
the relationships are as follows:
class Point { int x, y; }
class ColoredPoint extends Point { int color; }
final class Colored3dPoint extends ColoredPoint { int z; }
Point
is a superclass of class ColoredPoint
.
Point
is a superclass of class Colored3dPoint
.
ColoredPoint
is a subclass of class Point
.
ColoredPoint
is a superclass of class Colored3dPoint
.
Colored3dPoint
is a subclass of class ColoredPoint
.
Colored3dPoint
is a subclass of class Point
.
causes a compile-time error. If circularly declared classes are detected at run time, as classes are loaded, then a
class Point extends ColoredPoint { int x, y; }
class ColoredPoint extends Point { int color; }
ClassCircularityError
is thrown.
implements
clause in a class declaration lists the names of interfaces that are direct superinterfaces of the class being declared:
Interfaces:The following is repeated to make the presentation here clearer:
implements
InterfaceTypeList InterfaceTypeList:
InterfaceType
InterfaceTypeList,
InterfaceType
InterfaceType:Each InterfaceType must name an accessible interface type, or a compile- time error occurs. All interfaces in the current package are accessible. Interfaces in other packages are accessible if the host system permits access to the package and the interface is declared
TypeName
public
.
A compile-time error occurs if the same interface is mentioned two or more times in a single implements
clause, even if the interface is named in different ways; for example, the code:
class Redundant implements java.lang.Cloneable, Cloneable { int x; }results in a compile-time error because the names
java.lang.Cloneable
and
Cloneable
refer to the same interface.
An interface type I is a superinterface of class type C if any of the following is true:
public interface Colorable { void setColor(int color); int getColor(); }the relationships are as follows:
public interface Paintable extends Colorable { int MATTE = 0, GLOSSY = 1; void setFinish(int finish); int getFinish(); }
class Point { int x, y; }
class ColoredPoint extends Point implements Colorable { int color; public void setColor(int color) { this.color = color; } public int getColor() { return color; } }
class PaintedPoint extends ColoredPoint implements Paintable
{ int finish; public void setFinish(int finish) { this.finish = finish; } public int getFinish() { return finish; } }
Paintable
is a superinterface of class PaintedPoint
.
Colorable
is a superinterface of class ColoredPoint
and of class PaintedPoint
.
Paintable
is a subinterface of the interface Colorable
, and Colorable
is a superinterface of Paintable
.
PaintedPoint
has Colorable
as a superinterface both because it is a superinterface of ColoredPoint
and because it is a superinterface of Paintable
.
Unless the class being declared is abstract
, the declarations of the methods defined in each direct superinterface must be implemented either by a declaration in this class or by an existing method declaration inherited from the direct superclass, because a class that is not abstract
is not permitted to have abstract
methods.
interface Colorable { void setColor(int color); int getColor(); }causes a compile-time error, because
class Point { int x, y; };
class ColoredPoint extends Point implements Colorable { int color; }
ColoredPoint
is not an abstract
class but
it fails to provide an implementation of methods setColor
and getColor
of the
interface Colorable
.
It is permitted for a single method declaration in a class to implement methods of more than one superinterface. For example, in the code:
interface Fish { int getNumberOfScales(); }
interface Piano { int getNumberOfScales(); }
class Tuna implements Fish, Piano { // You can tune a piano, but can you tuna fish? int getNumberOfScales() { return 91; } }the method
getNumberOfScales
in class Tuna
has a name, signature, and return
type that matches the method declared in interface Fish
and also matches the
method declared in interface Piano
; it is considered to implement both.
On the other hand, in a situation such as this:
interface Fish { int getNumberOfScales(); }
interface StringBass { double getNumberOfScales(); }
class Bass implements Fish, StringBass { // This declaration cannot be correct, no matter what type is used. public ??? getNumberOfScales() { return 91; } }it is impossible to declare a method named
getNumberOfScales
with the same
signature and return type as those of both the methods declared in interface Fish
and in interface StringBass
, because a class can have only one method with a
given signature. Therefore, it is impossible for a single class to implement
both interface Fish
and interface StringBass
.
ClassBody:The scope of the name of a member declared in or inherited by a class type is the entire body of the class type declaration.
{
ClassBodyDeclarationsopt}
ClassBodyDeclarations:
ClassBodyDeclaration
ClassBodyDeclarationsClassBodyDeclaration ClassBodyDeclaration:
ClassMemberDeclaration
StaticInitializer
ConstructorDeclaration ClassMemberDeclaration:
FieldDeclaration
MethodDeclaration