Lecture
What Is a Class?
The concepts of class and object are so closely related that it is impossible to speak of an object without reference to its class. However, there is an important distinction between the two notions. Whereas an object denotes a concrete entity defined in time and space, a class defines only the abstraction of what is essential about the object. Thus, one can speak of the class "Mammals", which encompasses the characteristics common to all mammals. To designate a particular representative of the mammals, one must say "this is a mammal" or "that is a mammal".

A class represents a set of objects that share a common structure and a common behavior.
In everyday terms, the following definition of a class may be given: "a group, set, or kind marked by common attributes or a common attribute; a kind or category, distinguished by quality, capacities, or conditions" [17]. In the context of object-oriented analysis we give the following definition of a class:
A class is some set of objects that share a common structure and a common behavior.
Any particular object is simply an instance of a class. What, then, is not a class? An object is not a class, although we will see later that a class may be an object. Objects that are not related by commonality of structure and behavior cannot be grouped into a class, since by definition they have nothing in common except that they are all objects.
It is important to note that classes, as they are understood in most existing programming languages, are necessary but not sufficient for decomposing complex systems. Some abstractions are so complex that they cannot be expressed in terms of a simple class declaration. For example, at a sufficiently high level of abstraction, a graphical user interface, a database, or an accounting system as a whole are clearly objects, but not classes [One may attempt to express such abstractions with a single class, but no reusability or inheritance will be gained. Having an unwieldy interface is bad practice, since most clients use only a small part of it. Moreover, changing one part of this giant interface requires updating every one of its clients, regardless of whether the change substantively affected them. Nesting classes does not eliminate these problems, it only postpones them]. It is better to regard them as certain collections (clusters) of collaborating classes. Stroustrup calls such clusters components [18]. We, for reasons that will be explained in Chapter 5, call such clusters class categories.
Interface and Implementation
Meyer [19] and Snyder [20] have put forward the idea of programming by contract:
large problems must be divided into many small ones and delegated to smaller subcontractors. Nowhere does this idea manifest itself as vividly as in the design of classes.
By its very nature, a class is a general contract between an abstraction and all of its clients. The obligations of a class are expressed by its interface, and in strongly typed languages potential violations of the contract can be detected as early as compile time.
The idea of programming by contract leads us to distinguish between the outward appearance, that is, the interface, and the internal workings of a class, its implementation. The main thing in the interface is the declaration of the operations supported by instances of the class. To it may be added declarations of other classes, variables, constants, and exceptions that refine the abstraction the class is meant to express. The implementation of a class, by contrast, is of no interest to anyone but the class itself. For the most part, the implementation consists of the definitions of the operations declared in the class interface.
We may divide the interface of a class into three parts:
Different programming languages provide different combinations of these parts. The developer can set the access rights to one part of a class or another, thereby defining the client's scope of visibility.
In C++ in particular, all three of the listed access levels are stated explicitly. In addition, there is the mechanism of friends, by means of which outside classes may be granted the privilege of seeing the private and protected areas of a class. This breaks encapsulation, and so, as in life, friends must be chosen carefully. In Ada, declarations may be made private or public. In Smalltalk, all variables are private and all methods are public. In Object Pascal, all fields and operations are public, that is, there is no encapsulation at all [This refers to older versions of Object Pascal - Editor's note 2]. In CLOS, generic functions are public, while slots may be private, although their values can be found out anyway.
The state of an object is specified in its class through declarations of constants or variables placed in its protected or private part. They are thereby encapsulated, and changes to them do not affect clients.
An attentive reader may ask why the representation of an object is defined in the interface part of the class rather than in its implementation. The reasons are purely practical: otherwise object-oriented processors or extremely ingenious compilers would be required. When the compiler processes a declaration of an object such as:
DisplayItem item1;
it must know how much memory to allocate for it. If this information were contained in the class implementation, we would have to write that implementation in full before we could put its clients to work. That is, the whole point of separating interface from implementation would be lost.
The constants and variables that make up the representation of a class are known by various names. In Smalltalk they are called instance variables, in Object Pascal fields, in C++ class members, and in CLOS slots. We will often use these terms as synonyms.
The Life Cycle of a Class
The behavior of simple classes can be understood by studying the operations of their public part. However, the behavior of more interesting classes (such as moving an object of the class DisplayItem or scheduling for an instance of the class TemperatureController) involves the interaction of the various operations that make up the class. As was said above, objects of such classes act like little machines whose parts interact with one another, and since all such objects have one and the same behavior, the class can be used to describe their common semantics, ordered by time and events. As will be shown in Chapter 5, we can describe the dynamics of object behavior using the finite state machine model.
Comments