Friday, April 13, 2007

CLASSES(3)

CLASSES(3)

Superinterface: the optional implements clause in a class declaration introduces the names of interfaces that are direct superinterfaces of the class being declared.

Notation: interfaces:
implements InterfaceTypeList
where InterfaceTypeList may be one or many and are denoted by a TypeParameter specification which might be generic i.e TypeDeclSpecific TypeArgumentsopt

Given a class that could possibly be generic (C, n≥0, c≠Object),the direct superinterfaces of that class type are the types given in the implements clause of the declaration of C where C is a generic class declaration i.e (C, n>0), given a parameterized class type C where each T, denoted Ti, for 1≤i≤n, is a type, the direct superinterface of these parameterized class type are all types in the form I where I is a direct superinterface of C and theta is the substitution [F1 := T1, …, Fn := Tn].

Note:
1. each interface must name an accessible interface type
2. if type name is followed by type arguments, it must be invoked as-is, i.e as declared.
3. type arguments can never be wildcard if 2 is true.
4. an interface can not occur in an implements clause more than once.

An interface I is a superinterface of class type C if any of the following is true:
- I is a direct superinterface
- C has some direct superinterface J for which I is a superinterface.
- I is a direct superinterface of the direct superclass of C

(see jls for a simple, beautiful illustration in the section §8.1.5)

A class may not at the same time be a subtype of two interface types which are different invocations of the same generic interface (because they have similar erasures), or an invocation of a generic interface and a raw type naming that same generic interface.

class B implements I //erasure is /I/
class C extends B implements I //erasure /I/, similar to above

therefore, C cannot implement a type erasure twice.

Class body and Member declarations: a class body may contain declaration of members of a class, that is, fields, methods, nested class and interface declarations. A class body may also contain instance initialisers, static initializers, and constructor declarations.

The scope of member declarations in any class, whether explicitly declared or inherited, is the entire body of the class.

On shadowing, see the “Names, scope of a declaration” blog.

CLASS MEMBERS:
The members of a class type are all one of the following:
- members inherited from its direct superclass, except for class Object, which has no direct superclass.
- Members inherited from any direct superinterface.
- Members declared in the class body.

If a member is declared private, it cannot be inherited by subclasses of that class, but where declared as protected or public, other packages other than the one in which it is declared can inherit it.

The types of members of a class are denoted as:
a. for a field, its type
b. for a method, an ordered 3-tuple consisting of:
a. argument types: a list of the types of the arguments to the member method.
b. Return type: a return type of the method member
c. Throws clause: exception types declared in the throws clause of the method member.
Note: constructors, static initialisers and instance initialisers are not members and therefore are not inherited.

(there are fine examples in the jls at section §8.2 that well illustrate this concept.)

FIELD DECLARATORS: the variables of a class type are introduced by field declarations. Field declaration is of the notation:
FieldModifiersopt Type VariableDeclarators ;
Variable declarations can be one or many and are indicated by a variable identifier that could be a simple or qualified name or a name that is an array type. If a field is initialized on being declared, then it is done so with an expression or an appropriate array initialiser.

package examples;

public class AnyClassWithVariable {
//myfirstvar, mysecondvariable, simple named variables
//am sure you can do qualified names easily!!!
int myfirstvar;
float mysecondvar = 0.006453f; //initialised and declared

//an array variable stringer, not initialised
String[] stringer = new String[3];

//another that is initialised
int[] twoshort = {3, 5, 7};
}

Note:
1. a compile time error is reported if the body of a class declaration declares 2 fields with the same name, but methods, types and fields may have the same name since they are used in different context and disambiguated by different lookup.
2. Hiding fields: a field declared in a subclass with the same name as another in a superclass will hide the field in the superclass or superinterface. Hiding here corresponds to resolution mechanism for field name conflicts. In hiding, the 2 fields may have different type.
3. Shadowing fields: declarations of any accessible field in enclosing classes or interfaces, and any local variable, formal method parameter and exception handler parameter with the same names as that field will result in shadowing.
An illustration:

package examples;

public class AnyClassWithVariable {
//myfirstvar, mysecondvariable, simple named variables
//am sure you can do qualified names easily!!!
int myfirstvar;
float mysecondvar = 0.006453f; //initialised and declared

//an array variable stringer, not initialised
String[] stringer = new String[3];

//another that is initialised
int[] twoshort = {3, 5, 7};

//shadowing of mysecondvar, reflected in main of Loader
void shadowMethod(){
float mysecondvar = 0.098765f;
System.out.println(mysecondvar); //sure to shadow
}
}

public class ClassAndVariable extends AnyClassWithVariable {
int myfirstvar = 400;
}

class Loader {

public static void main(String[] args) {
AnyClassWithVariable tester = new AnyClassWithVariable();

//mysecondvar in scope of class declaration
System.out.println("global mysecondvar is:
"+tester.mysecondvar);

//here shadowed in shadowMethod
System.out.print("global mysecondvar is shadowed by
method's mysecondvar: ");
tester.shadowMethod();

//to start to show hiding, we instantiate the subclass
ClassAndVariable test2 = new ClassAndVariable();

//which myfirstvar int field will test2 give us
System.out.println("Of the two myfristvar fields, test2
gives: "+test2.myfirstvar);
System.out.println("which is hiding the uninitialised one,
AnyClassWithVariable.myfristvar.");

//to get this field, use the qualified name within the
//method scope
}
}

Field modifiers: field modifiers are one of the following:

public protected private static final transient volatile

the appearance of a field modifier must be distinct although ordering is not defined, the above order is customary in java programming.

If an annotation a corresponds to an annotation type T, then T has a (meta-)annotation m that corresponds to annotation.Target, then m must have an element whose value is annotation.ElementType.FIELD, or a compile-time error results.

Static fields: if a field is declared static, there exists exactly one incarnation of the field, no matter how many instances (or zero) of the class that may eventually be instantiated. A static field is sometimes called a class variable and is instantiated on class initialization.

A field not declared static (or called a non-static field) is called an instance variable. An instance variable has distinct incarnations for every instance of a class.
(see the example in §8.3.1.1 for class and instance variable distinction. Well explained. )

Final fields: class and instance variables can be declared final.

It is a compile time error if a blank final (a final variable whose declaration lacks an initializer) class variable is not definitely assigned by a static initialiser of the class in which it is declared.

A blank final instance variable must be definitely assigned at the end of every constructor of the class in which it is declared, otherwise, a compile time error results.

Transient fields: variables declared transient will never be part of the persistent state of an object, such that the system service does not save this variable in persistent storage.

Volatile fields: when a variable is accessed by more than one thread with at least one write operation on the variable followed by any number of reads, the java programming language gives the programmer the facility of locking the variable to ensure consistent and reliable updating of the variable. The modifier volatile supplements this locking making sure that the java memory model gives all threads a consistent value for this variable.

(to be continued)

No comments: