Contents | Prev | Next | The T Language Specification, Version 2 Spring 2006 |
CHAPTER 5
Class declarations define new reference types and describe how they are implemented (§5.1).
Each class except Object
is an extension of
(that is, a subclass of) a single existing class (§5.1.3).
The body of a class declares members (fields and methods), constructors and destructors (§5.1.5). The scope (§6.3) of a member (§5.2) is the entire declaration of the class to which the member belongs. The members of a class include both declared and inherited members (§5.2). Newly declared fields can hide fields declared in a superclass. Newly declared methods can override methods declared in a superclass.
Field declarations (§5.3) describe instance variables, which are freshly incarnated for each instance of the class.
Method declarations (§5.4) describe code that may be invoked by method invocation expressions (§8.10). A method is invoked with respect to some particular object that is an instance of the class type.
Method names may be overloaded (§5.4.7).
Constructors (§5.5) are similar to methods, but cannot be invoked directly by a method call; they are used to initialize new class instances. Like methods, they may be overloaded (§5.4.7).
Destructors (§5.6) are similar to methods, but cannot be invoked directly by a method call; they are used to perform termination housekeeping before a system reclaims the memory of an object that is an instance of a class.
A class declaration specifies a new reference type:
ClassDeclaration:
class
Identifier Superopt ClassBody
The Identifier in a class declaration specifies the name of the class. A compile-time error occurs if a class has the same name as any other class in the program.
The optional 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.
If the class declaration for any class has no extends
clause,
then the class has the class Object
as its implicit direct
superclass.
Super:
extends
ClassType
The following is repeated from §2.3 to make the presentation here clearer:
ClassType: TypeName
The ClassType must name a class type, or a compile-time error occurs.
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:
Class C is said to be a superclass of class A whenever A is a subclass of C.
A class C directly depends on a type T if T is mentioned in the extends clause of C. A class C depends on a reference type T if any of the following conditions hold:
It is a compile-time error if a class depends on itself.
For example:
class Point extends ColoredPoint { int x, y; }
class ColoredPoint extends Point { int color; }
causes a compile-time error.
A class body may contain declarations of members of the class, that is, fields (§5.3) and methods (§5.4). A class body may also contain declarations of constructors and destructors (§5.5) for the class.
ClassBody: { ClassBodyDeclarationsopt } ClassBodyDeclarations: ClassBodyDeclaration ClassBodyDeclarations ClassBodyDeclaration ClassBodyDeclaration: ClassMemberDeclaration ConstructorDeclaration DestructorDeclaration ClassMemberDeclaration: FieldDeclaration MethodDeclaration ;
The scope of a declaration of a member m declared in or inherited by a class type C is the entire body of C.
The members of a class type are all of the following:
Object
, which has no direct superclass
Constructors and destructors are not members and therefore are not inherited.
The variables of a class type are introduced by field declarations:
FieldDeclaration: Type VariableDeclarators ; VariableDeclarators: VariableDeclarator VariableDeclarators , VariableDeclarator VariableDeclarator: VariableDeclaratorId VariableDeclaratorId: Identifier VariableDeclaratorId [ ]
The Identifier in a FieldDeclarator may be used in a name to refer to the field. Fields are members; the scope (§4.3) of a field declaration is specified in §5.1.2. More than one field may be declared in a single field declaration by using more than one declarator; the Type apply to all the declarators in the declaration. Variable declarations involving array types are discussed in §6.2.
It is a compile-time error for the body of a class declaration to declare two fields with the same name.
Methods, types, and fields may have the same name, since they are used in different contexts and are disambiguated by different lookup procedures (§4.4).
If the class declares a field with a certain name, then the declaration of that field is said to hide any declarations of fields with the same name in superclasses of the class.
If a field declaration hides the declaration of another field, the two fields need not have the same type.
A class inherits from its direct superclass all the fields of the superclass that are not hidden by a declaration in the class.
It is not possible for a class to inherit more than one field with the same name.
A hidden field can be accessed by using a field access expression (§8.9)
that contains the keyword super
.
A method declares executable code that can be invoked, passing a fixed number of values as arguments.
MethodDeclaration: MethodHeader MethodBody MethodHeader: ResultType MethodDeclarator ResultType: Type MethodDeclarator: Identifer ( FormalParameterListopt )
A method declaration specifies the type of value that the method returns.
The Identifier in a MethodDeclarator may be used in a name to refer to the method. A class can declare a method with the same name as the class or a field of the class.
A declaration form for a method that returns an array is allowed to place (some or all of) the empty bracket pairs that form the declaration of the array type after the parameter list. This is supported by the production:
MethodDeclarator: MethodDeclarator [ ]
It is a compile-time error for the body of a class to have as members two methods with the same signature (§5.4.2) (name, number of parameters, and types of any parameters). Methods and fields may have the same name, since they are used in different contexts and are disambiguated by the different lookup procedures (§4.4).
The formal parameters of a method or constructor, if any, are specified by a list of comma-separated parameter specifiers. Each parameter specifier consists of a type and an identifier (optionally followed by brackets) that specifies the name of the parameter:
FormalParameterList: FormalParameter FormalParameterList , FormalParameter FormalParameter: Type VariableDeclaratorId
The following is repeated from §5.3 to make the presentation here clearer:
VariableDeclaratorId: Identifier VariableDeclaratorId [ ]
If a method or constructor has no parameters, only an empty pair of parentheses appears in the declaration of the method or constructor.
If two formal parameters of the same method or constructor are declared to have the same name (that is, their declarations mention the same Identifier), then a compile-time error occurs.
When the method or constructor is invoked (§8.10), the values of the actual argument expressions initialize newly created parameter variables, each of the declared Type, before execution of the body of the method or constructor. The Identifier that appears in the DeclaratorId may be used as a simple name in the body of the method or constructor to refer to the formal parameter.
The scope of a parameter of a method or constructor is the entire body of the method or constructor.
The signature of a method consists of the name of the method and the number and types of formal parameters to the method.
A class may not declare two methods with the same signature, or a compile-time error occurs.
A method body is a block of code that implements the method.
MethodBody: Block
If an implementation requires no executable code, the method body should be written as a block that contains no statements: "{ }".
Since a method must always have a return type, then every return statement (§7.8) in its body must have an Expression.
Moreover, a method may only explicitly return by using a return
statement that provides a value return. Otherwise, the method may "drop off"
the end of its body by executing an implicit return at the very end of its method body; the value of the expression for this implicit return is the same as the default value for the return type of the method (i.e. 0 for int
and null
for reference types).
A class inherits from its direct superclass all the methods of the superclass that are not overridden (§5.4.4.1) by the declaration in the class.
A method m1 declared in a class C overrides another method with the same signature, m2, declared in class A if both:
An overridden method can be accessed by using a method invocation expression
(§8.10) that contains the keyword super
.
It is not possible for a class to inherit more than one method with the same signature.
Such a situation causes a compile-time error.
A compile-time error occurs if, comparing the method with each of the other of the inherited methods, for any such pair, they have different return types.
If two methods of a class (whether both declared in the same class, or both inherited by a class, or one declared and one inherited) have the same name but different signatures, then the method name is said to be overloaded. This fact causes no difficulty and never of itself results in a compile-time error.
There is no required relationship between the return types of two methods with the same name but different signatures.
Methods are overridden on a signature-by-signature basis.
If, for example, a class declares two methods with the same name, and a subclass overrides one of them, the subclass still inherits the other method.
When a method is invoked (§8.10), the number of actual arguments and the compile-time types of the arguments are used, at compile time, to determine the signature of the method that will be invoked (§8.10.2). The actual method to be invoked will be determined at run time, using dynamic method lookup (§8.10.4).
A constructor is used in the creation of an object that is an instance of a class:
ConstructorDeclaration: ConstructorDeclarator ConstructorBody ConstructorDeclarator: TypeName ( FormalParameterListopt )
The TypeName in the ConstructorDeclarator must be the name of the class that contains the constructor declaration; otherwise a compile-time error occurs. In all other respects, the constructor declaration looks just like a method declaration that has no result type.
Constructors are invoked by class instance creation expressions, and by explicit constructor invocations from other constructors (§5.5.5). Constructors are never invoked by method invocation expressions.
Constructors are not members. They are never inherited and therefore are not subject to hiding or overriding.
The formal parameters of a constructor are identical in structure and behavior to the formal parameters of a method.
The signature of a constructor consists of the number and types of formal parameters to the constructor. A class may not declare two constructors with the same signature, or a compile-time error occurs.
The first statement of a constructor body may be an explicit invocation of another constructor of the same class or of the direct superclass (§5.5.3.1).
ConstructorBody: { ExplicitConstructorInvocationopt BlockStatementsopt }
It is a compile-time error for a constructor to directly or indirectly invoke
itself through a series of one or more explicit constructor invocations
involving this
.
ExplicitConstructorInvocation:this
( ArgumentListopt ) ;super
( ArgumentListopt ) ;
Explicit constructor invocation statements can be divided into two kinds:
this
. They are used to invoke an alternate constructor of
the same class.
super
. They are used to invoke a constructor of the direct
superclass.
An explicit constructor invocation statement in a constructor body may not
refer to any variables or methods declared or inherited in the object being
constructed,
or use this
or super
in any expression;
otherwise, a compile-time error occurs.
The evaluation of an explicit constructor invocation proceeds in several steps:
super();
", an invocation of the
constructor of its direct superclass that takes no arguments. Since class
Object
is a fundamental superclass of all classes, invocation of
the superclass constructor will precede the execution of the local class
constructor during the constructor invocation step.
Overloading of constructors is identical in behavior to overloading of methods. The overloading is resolved at compile time by each class instance creation expression.
If a class contains no constructor declarations, then a default constructor that takes no parameters is automatically provided.
The default constructor takes no parameters and simply implicitly invokes the superclass constructor with no arguments. A compile-time error occurs if a default constructor is provided by the compiler but the superclass does not have a constructor that takes no arguments.
A destructor is used to perform termination housekeeping before a system reclaims the memory of an object that is an instance of a class:
DestructorDeclaration: DestructorDeclarator DestructorBody DestructorDeclarator: ~TypeName ( )
The TypeName in DestructorDeclarator must be the name of the class that contains the destructor declaration. same as the name used in a constructor.
There can only be a single destructor per class. Destructors may not be passed any arguments (§5.6.1). Just like constructors, destructors are not considered members of the class: they are never inherited and therefore are not subject to hiding or overriding. Unlike constructors, destructors may not be overloaded (§5.6.4).
Destructors may only be used with reference types, the system reclaims integers automatically.
Unlike class methods or class constructors, destructors cannot have any parameters. It is a compile-time error to try to pass arguments to a destructor.
Destructors do not have any formal parameters. They are identified at compile time by a '~' symbol followed by a class name and an empty argument list. A class may not declare two destructors, or a compile-time error will occur.
Like constructors, destructors are not methods and do not return anything explicitly.
The primordial Object
class has a destructor with an empty body.
To release the allocated memory, destructors must be explicitly invoked
on reference type objects when the objects are no longer needed.
Destructors are invoked by utilizing the delete
statement (§7.9).
The delete
statement includes an expression that should
produce a reference value that denotes the object to be deleted.
When a destructor for a class other than the primordial Object
completes, the destructor for the class' direct superclass is automatically
invoked.
The object's memory is freed after all superclass destructors finish.
It is a compile time error to try to overload a destructor.
The compiler automatically provides a default destructor if a class contains no destructor declaration. The single task of a default destructor is to implicitly call the destructor of the direct superclass.
The primordial Object
class does not call a superclass
destructor upon the destruction of its instances, because it has
no superclass.
Contents | Prev | Next | The T Language Specification, Version 2 Spring 2006 |
Author(s): Octavian Filoti (§5.1-5.4), and Dmitri Garbuzov (§5.5-5.6)