Contents | Prev | Next The T Language Specification, Version 2
Spring 2006

CHAPTER 5

Classes


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.

5.1 Class Declaration

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.

5.1.1 Superclasses and Subclasses

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.

5.1.2 Class Body and Member Declarations

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.

5.2 Class Members

The members of a class type are all of the following:

Constructors and destructors are not members and therefore are not inherited.

5.3 Field Declarations

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.

5.4 Method Declarations

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).

5.4.1 Formal Parameters

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.

5.4.2 Method Signature

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.

5.4.3 Method Body

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).

5.4.4 Inheritance and Overriding

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.

5.4.4.1 Overriding

A method m1 declared in a class C overrides another method with the same signature, m2, declared in class A if both:

  1. C is a subclass of A.
  2. Either

An overridden method can be accessed by using a method invocation expression (§8.10) that contains the keyword super.

5.4.4.2 Inheriting Methods with the Same Signature

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.

5.4.5 Overloading

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).

5.5 Constructor Declarations

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.

5.5.1 Formal Parameters

The formal parameters of a constructor are identical in structure and behavior to the formal parameters of a method.

5.5.2 Constructor Signature

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.

5.5.3 Constructor Body

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.

If a constructor body does not begin with an explicit constructor invocation, then the constructor body is implicitly assumed by the compiler to begin with a superclass constructor invocation "super();", an invocation of the constructor of its direct superclass that takes no arguments. A compile-time error occurs if an implicit superclass constructor invocation is assumed by the compiler but the superclass does not have a constructor that takes no arguments.

5.5.3.1 Explicit Constructor Invocations




ExplicitConstructorInvocation:

	this ( ArgumentListopt ) ;

	super ( ArgumentListopt ) ;



Explicit constructor invocation statements can be divided into two kinds:

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:

5.5.4 Constructor Overloading

Overloading of constructors is identical in behavior to overloading of methods. The overloading is resolved at compile time by each class instance creation expression.

5.5.5 Default Constructor

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.

5.6 Destructor Declarations

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.

5.6.1 Formal Parameters

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.

5.6.2 Destructor Signature

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.

5.6.3 Destructor Body

Like constructors, destructors are not methods and do not return anything explicitly.

The primordial Object class has a destructor with an empty body.

5.6.4 Destructor Invocations

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.

5.6.5 Destructor Overloading

It is a compile time error to try to overload a destructor.

5.6.6 Default 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)