Previous Up Next

Features

The body of a class definition consists of a list of feature definitions. A feature is either an \(\it attribute\) or a \(\it method\). An attribute of class \(\rm A\) specifies a variable that is part of the state of objects of class \(\rm A\). A method of class \(\rm A\) is a procedure that may manipulate the variables and objects of class \(\rm A\).

One of the major themes of modern programming languages is \(\it information\ hiding\), which is the idea that certain aspects of a data type's implementation should be abstract and hidden from users of the data type. Cool supports information hiding through a simple mechanism: all attributes have scope local to the class, and all methods have global scope. Thus, the only way to provide access to object state in Cool is through methods.

Feature names must begin with a lowercase letter. No method name may be defined multiple times in a class, and no attribute name may be defined multiple times in a class, but a method and an attribute may have the same name.

A fragment from \(\rm list.cl\) illustrates simple cases of both attributes and methods:

class Cons inherits List {
	xcar : Int;
	xcdr : List;

	isNil() : Bool { false };

	init(hd : Int, tl : List) : Cons {
		{
			xcar <- hd;
			xcdr <- tl;
			self;
		}
	};
...
};

In this example, the class \(\rm Cons\) has two attributes \(\rm xcar\) and \(\rm xcdr\) and two methods \(\rm isNil\) and \(\rm init\). Note that the types of attributes, as well as the types of formal parameters and return types of methods, are explicitly declared by the programmer.

Given object \(\rm c\) of class \(\rm Cons\) and object \(\rm l\) of class \(\rm List\), we can set the \(\rm xcar\) and \(\rm xcdr\) fields by using the method \(\rm init\):

c.init(1,l)

This notation is \(\it object \HY oriented\ dispatch\). There may be many definitions of \(\rm init\) methods in many different classes. The dispatch looks up the class of the object \(\rm c\) to decide which \(\rm init\) method to invoke. Because the class of \(\rm c\) is \(\rm Cons\), the \(\rm init\) method in the \(\rm Cons\) class is invoked. Within the invocation, the variables \(\rm xcar\) and \(\rm xcdr\) refer to \(\rm c\)'s attributes. The special variable \(\rm self\) refers to the object on which the method was dispatched, which, in the example, is \(\rm c\) itself.

There is a special form \(\rm new\ C\) that generates a fresh object of class \(\rm C\). An object can be thought of as a record that has a slot for each of the attributes of the class as well as pointers to the methods of the class. A typical dispatch for the \(\rm init\) method is:

(new Cons).init(1,new Nil)

This example creates a new cons cell and initializes the "car" of the cons cell to be 1 and the "cdr" to be \(\rm new\ Nil\).(2) There is no mechanism in Cool for programmers to deallocate objects. Cool has \(\it automatic\ memory\ management\); objects that cannot be used by the program are deallocated by a runtime garbage collector.

Attributes are discussed further in Section 5 and methods are discussed further in Section 6.

Previous Up Next