Home

Documentation

* Programming Guide * CJDT User Guide * Publications * Tutorial * Language Spec.

Examples

Downloads

Source Code

FAQ

Community Info

About Us

 

 
Search:
 
ST Logo
TUD Logo
<< | Contents | Dependent Types >>

Classes, Refinement and Composition

Types of Classes (cls.types)

(cls.types.1) Caesar supports two types of classes Java classes and Caesar classes.

Def: Java classes are conventional classes, complying to JLS.

Def: Caesar classes are extended Java classes, which provide additional Caesar specific features and have slightly different semantics, which will be defined further in this specification.

(cls.types.2) Java classes are declared with keyword class

(cls.types.3) Ceasar classes are declared with keyword cclass.

Nesting (cls.nest)

(cls.nest.1) Caesar class can be defined on top level or be nested within another Caesar class.

Def: Nested Caesar classes are virtual classes.

Def: A Caesar class having nested classes is also called collaboration. The directly enclosing class of a virtual class is the collaboration of the class.

(cls.nest.2) The name of a nested class must be unique within the collaboration.

(cls.nest.3) Unlimited levels of nesting are allowed.

Restrictions

(cls.nest.4) A Java class cannot be nested within a Caesar class.

(cls.nest.5) A Caesar class cannot be nested within a Java class.

(cls.nest.6) Interfaces cannot be nested within a Caesar class.

Example: In List.1 Graph is a top level Caesar class. Classes Node and Edge are nested within Graph, so they are virtual classes of Graph, and Graph is the collaboration of Edge and Node.

Listing 1.
 
package examples.graph;

public cclass Graph {
   public cclass Node { 
      ...
   }
   public cclass Edge { 
      ...
   }
}

(cls.nest.7) Nested Caesar class can also be defined outside the collaboration in a separate file. At the beginning of such file there must be a cclass declaration with the fully qualified name of the collaboration. This declaration replaces package declaration for the file.

Example: In List.2 class UndirectedEdge is a virtual class of Graph, but defined in a separate file. Therefore there is a cclass declaration with fully qualified name of Graph at the beginning of the file instead of package declaration.

Listing 2.
 
/* File UndirectedEdge.java */
cclass examples.graph.Graph;

cclass UndirectedEdge extends Edge {
   ...
}

Outer Object (cls.outer)

(cls.outer.1) Instance of a nested class always contains a reference to an instance of the directly enclosing class.

Def: The instance of the enclosing class is called outer object.

(cls.outer.2) Outer object can be accessed through qualified this in a similar way as in Java.

(cls.outer.3) Outer access can also be determined implicitly for method calls.

(cls.outer.4) Outer access from an instance of a top level Caesar class is not allowed.

(cls.outer.5) Only the public members of the outer object can be accessed.

(cls.outer.6) Outer reference cannot be changed after the instantiation of the object.

Example: In List.3 any instance of class Inner has a reference to an instance of class Outer and can call its public methods.

It can be determined implicitly that the call of method methB() is a call on outer object.

Method methA() also exists in class Inner, so outer must be referenced explicitly using this, qualified with Outer.

Listing 3.
 
public cclass Outer {
   public void methA() { }
   public void methB() { }
   
   public cclass Inner { 
      public void methA() { }

      public void test() {
         methA(); /* call on this */
         methB(); /* call on outer */
         Outer.this.methA(); /* call on outer */  
      }
   }
}

Class Inheritance (inh.types)

(inh.types.1) There are two types of inheritance between Caesar classes - generalization and overriding

Def: Generalization (specialization) – logical, explicitly defined inheritance relationship between Caesar classes.

Def: Overriding (refinement) – an overriding class implicitly inherits from its overridden versions.

Def: The inherited class is called superclass, the inheriting class is called subclass. So superclasses of a class are its generalizations and the overridden classes. The subclasses of a class are its specializations and overriding classes.

(inh.types.2) Caesar class can implement any number of interfaces. Implemented interfaces are listed in implements clause and separated by commas.

Different types of classes cannot be mixed in extends declarations:
  • (inh.types.3) A Java class cannot extend a Caesar class.
  • (inh.types.4) A Caesar class cannot extend a Java class.

Class Generalization (inh.gener)

(inh.gener.1) A Caesar class can be declared as a specialization of any number of Caesar classes. The generalizations of the class are listed in extends clause and separated by mixin operator “&”.

(inh.gener.2) A Caesar class inherits all members and nested classes from its generalizations.

(inh.gener.3) Only the classes of the same collaboration can stand in generalization relationship.

(inh.gener.4) Top level Caesar class can inherit only from other top level Caesar classes.

(inh.gener.5) Cross collaboration generalization relationships are disallowed.

(inh.gener.6) Generalization relationships between Caesar classes with different nesting level are disallowed.

Example: In the List.4 there are generalization relationships on the top level as well as inside the collaborations.

CompositeShapes has two generalizations: Shapes and CompositePattern

Component is generalization of Composite in the collaboration CompositePattern. Shape is generalization of Circle in the collaboration Shapes.

Collaboration CompositeShapes inherits all generalization relationships from CompositePattern and Shapes. It also defines new generalization relationships. Composite and Shape are generalizations of CompositeShape. Shape is also defined as specialization of Component.

Listing 4.
 
public cclass CompositePattern {
   public cclass Component { 
      ...
   }
   public cclass Composite extends Component { 
      ...
   }   
}
public cclass Shapes {
   public cclass Shape {
      ...
   }
   public cclass Circle extends Shape {
      ...
   }
}
public cclass CompositeShapes extends Shapes & CompositePattern {
   public cclass CompositeShape extends Composite & Shape {
      ...
   }
   public cclass Shape extends Component {
      ...
   }
}

The complete generalization hierarchy within CompositeShapes is:


Overriding Classes (inh.overr)

(inh.overr.1) Collaboration can define a nested virtual class with the same name as one of the inherited virtual classes. In this case the newly defined virtual class overrides the inherited class in the context of the collaboration. The overriding class is known as a refinement or a further-binding.

(inh.overr.2) Collaboration can inherit multiple virtual classes with the same name from its superclasses. All these classes are overridden by a new virtual class with the same name. If such class does not exist, it is implicitly created.

(inh.overr.3) Overriding class inherits all members, nested virtual classes from all overridden classes.

(inh.overr.4) Overriding class inherits all generalizations of the overridden classes.

(inh.overr.5) The inherited generalizations need not to be repeated in the overriding class.

(inh.overr.6) Overriding class can introduce new generalizations by listing them in the extends clause.

Example: In the List.4 Shape of CompositeShapes overrides the Shape class inherited from collaboration Shapes. So CompositeShapes.Shape is overriding class of Shapes.Shape.

CompositeShapes.Circle is overriding class of Shapes.Circle. This class is not overridden explictly, but it still will be different, because its generalization Shape has been overriden.

Mixin Linearization

A class may inherit a method with the same name from multiple super classes. CaesarJ? resolves such conflicts automatically using mixin linearization process.

Def: All Caesar class declarations are considered as mixins, i.e. classes with replaceable superclass, so that they can be flexibly ordered to various linear inheritance sequences. This ordering process is called mixin linearization.

Linearization Effect (inh.resol)

For each Caesar class C, all inherited class declarations (mixins) and its own declaration are ordered into a sequence [M1, M2, … Mn] with following effect:

(inh.resol.1) If there are several mixins, which define a class member with the same name, C inherits the member definition from the leftmost mixin.

(inh.resol.2) The lookup for a super method call in class C starts from M2 and continues along the sequence until the method with required name is found.

Linearization Rules (inh.linear)

Mixin list of class C is defined according following rules:

  • (inh.linear.1) All inherited mixins of class C appear in the mixin list.

  • (inh.linear.2) The same mixin is included only once in the list.

  • (inh.linear.3) Linearization must preserve generalization links, i.e. if class A is a generalization of class B in the collaboration of class C, all mixins of A are positioned after all mixins of B.

  • (inh.linear.4) Linearization must preserve the class ordering in extends clause, i.e. if in the extends clause of any of the mixins, inherited by class C, generalization A is listed after generalization B, then all mixins of A must also be ordered after all mixins of B.

  • (inh.linear.5) Linearization must preserve overriding sequence, i.e. if mixin A1 overrides mixin A2, A1 is positioned before A2.

(inh.linear.6) If no mixin sequence is possible, which complies to the above rules, the rule (inh.linear.4) is ignored.

(inh.linear.7) If the above rules to not restrict order between mixins Mi and Mj, their ordering is not determined by the specification and left free for compiler implementation.

Example: In the List.4 the mixins of CompositeShapes.Circle are all its inherited class declarations, i.e. the declarations of Circle and the declarations all its generalizations: Shape and Component. So, the mixins of CompositeShapes.Circle are:

Shapes.Circle
Shapes.Shape
Composite.Component
CompositeShapes.Shape

According inh.linear.3 the mixin order must follow generalization hierarchy, so the mixins of Circle must be followed by mixins of Shape, and the mixins of Shape must be followed by mixins of Component:

[Shapes.Circle, Shapes.Shape, CompositeShapes.Shape, CompositePattern.Component]

This order is still not correct. CompositeShapes.Shape overrides Shapes.Shape, so according inh.linear.5 CompositeShapes.Shape must be placed before Shapes.Shape. So the correct linearization of CompositeShapes.Circle mixins is:

[Shapes.Circle, CompositeShapes.Shape, Shapes.Shape, CompositePattern.Component]

The mixin list of CompositeShapes.CompositeShape is

[CompositeShapes.CompositeShape, CompositePattern.Composite, CompositeShapes.Shape, Shapes.Shape, CompositePattern.Component]

This linearization does not contradict generalization and overriding relationships. There is no relationship is define between Shape and Composite, but Composite still must be positioned before Shape, because these classes appear in this order in the extends clause of CompositeShapes.CompositeShape (see inh.linear.4).

Constructors (cls.constr)

(cls.constr.1) Caesar class may have only the default constructor - the constructor without parameters.

(cls.constr.2) The constructors of all superclasses are automatically called in the order defined by mixin linearization rules.

Visibility (cls.visib)

(cls.visib.1) A Caesar class must have public visibility

(cls.visib.2) Caesar class methods may have public, protected or private visibility

(cls.visib.3) Non-static class fields may have protected or private visibility

(cls.visib.4) Static class fields may have public, protected or private visibility

(cls.visib.5) Class members with private visibility are visible only within the same class declaration, i.e. they are not visible in the overriding classes.

(cls.visib.6) Class members with protected visibility are visible in all subclasses of the class.

Instantiation (cls.inst)

(cls.inst.1) A top level Caesar class is instantiated using simple new operator.

(cls.inst.2) A virtual class can be instantiated only in the context of an instance of its collaboration. The qualified new operator is used.

(cls.inst.3) Expression exp.new cls(), where exp is any expression returning collaboration object, has following semantics:

  • Virtual class cls, declared within the run-time class of exp, is instantiated.

  • Class cls must be declared in the statically known class of exp.

  • The object, returned by exp, becomes the outer object of the new instance of cls.

(cls.inst.4) Unqualified instantiation of a virtual class new cls() is assumed as instantiation in the context of this instance or some outer of this, which contains class cls.

Example: In List.5 Node is a virtual class, so it cannot be instantiated directly. It can be instatiated only in the context of a Graph object.

Expression new Node() inside Graph class is assumed as instantiation in the context of this instance, i.e. this.new Node().

Expression new Node() inside Edge class is assumed as instantiation in the context of the enclosing graph instance, i.e. Graph.this.new Node().

Listing 5.
 
public cclass Graph {
   public Node defaultNode() {
      return new Node(); /* OK */
   }
   public cclass Node { 
      ...
   }
   public cclass Edge {
      Node n1, n2;
      public void disconnectEnd() {
          n2 = new Node(); /* OK */
      }
   }
}
public class Test {
   public void test() {
       Graph.Node n = new Graph.Node(); /* error! */
       
       Graph g = new Graph();   /* OK */
       g.Node n = g.new Node(); /* OK */      
   }
}

Abstract Classes (cls.abstr)

(cls.abstr.1) Caesar classes can be declared as abstract using abstract modifier.

(cls.abstr.2) An implicitly inherited class is abstract if and only if all the classes, which it overrides, are abstract.

(cls.abstr.3) A concrete virtual class cannot be overriden by an abstract class. (Nevertheless it can still have abstract specializations)

(cls.abstr.4) Abstract collaborations can contain concrete virtual classes, as well as concrete collaborations can contain abstract virtual classes.

(cls.abstr.5) A Caesar class can contain abstract methods if and only if it is abstract or some of its enclosing collaborations is abstract.

(cls.abstr.6) A top level abstract Caesar class cannot be instantiated.

(cls.abstr.7) Virtual class instantiation of form exp.new cls is allowed if and only if cls is not abstract in the statically known type of exp.

<< | Contents | Dependent Types >>