• Aucun résultat trouvé

Designing a New Class

Dans le document til Smalltalk (Page 56-61)

Sma/ltalk Fundamentals

2.4 CONTROL STRUCTURES WITH MESSAGE-PASSING

2.5.1 Designing a New Class

The first step in designing a new class is to develop a specification for the class; i.e., to define the message protocol or outside view of the new class. The specification should provide all the information required by users of the class butonly that information. No information superfluous to the needs of users should be provided. The specification of the class should be completedbeforeany implementation issues are considered. Developing the specification consists of the following three steps:

1. Listing the names of the operations required.

2. Fleshing out the operations by describing the parameters in detail.

3. Specifying the semantics of each operation informally.

We will assume, for brevity's sake, that we only wish to create, add, and multiply complex numbers and also access and modify their real and imaginary parts.

I 'Ill'!

2.5.2 Class Protocol versus Instance Protocol

The message protocol for a class is described in two parts: the class protocol and the instance protocol.

Class Protocol A description of the protocol understood by a class.

Instance Protocol A description of the protocol understood by instances of a class.

The class protocol describes messages that are sent to the class rather than to the instances. Typically, the class protocol contains protocol for creating and initializing new instances of a class. Classes can be thought of as factories for creating instances. For example, it is the responsibility of class Complex to create new instances of the class. The expression

Complex newWithR_I: 1.0 endlmeginary: 3.5

sends the message newWithReal: 1.0 andImaginary: 3.5 to the class Complex. The intent is to return a new instance of class Complex with real and imaginary components initialized to 1.0 and 3.5 respectively. For class Complex, the class protocol might be specified as follows:

instance creation

nawWithReel: realPart endlmeginery: imaginaryPart

Returns an instance of class Complex with real part reelPert and imaginary part imeginaryPert.

Method categories are used in Smalltalk to group together methods that provide similar functionality. For example, the class method newWithReal:andImaginary: would be placed in a category with the name instance creation.Category names have no semantic significance - they are used externally for documentation purposes. Internally, category names are used by the programming environment to group related methods.

The instance protocol is the message protocol supported by instances of the class;

Le., messages that may be sent to any instance of the class. For example, the message protocol for adding two complex numbersispart of the instance protocol. In the expression

complex1+complex2

the receiver of the message+complex2 is the instance complex!. A subset of the instance protocol for the class Complex might be the following:

accessing

~IPert

Returns the real component of the receiver.

imeginaryPert

Returns the imaginary component of the receiver.

Chapter 2 Smalltalk Fundamentals 41

realPart:realValue

Sets the real component of the receiver to realValue. Returns the modified receiver.

imaginaryPart:imaginaryValue

Sets the imaginary component of the receiver to imaginaryValue.Returns the modified receiver.

arithmetic + aComplex

Returns a complex number equal to the sum of the receiver and the argumentaComplex.

• aComplex

Returns a complex number equal to the product of the receiver and the argumentaComplex.

Ifthe instance and class protocols for Complex are sufficiently complete, we should be able to write code that manipulates complex numbers, despite the fact that we have yet to consider how to represent complex numbers or how to implement any of the operations. For example, the following message expressions would create two complex numbers and then compute two more, one equal to the sum of the originals and the other equal to their product.

It is a good practice totry"programming" with a new class as soon as its protocol has been specified. More often than not, this process reveals deficiencies in the protocol. Clearly, it is better to discover such problems at the specification stage rather than after the class has been implemented.

I complex1 complex2 complexSum complexProduct I complex1 ~ComplexnewWithReal:2.5andlmaginary:3.1.

complex2~ComplexnewWithReal:-1.0andlmaginary:0.5.

complexSum~complex1+ complex2.

complexProduct~complex1 • complex2

2.5.3 Implementing a Class Description

The inside view of a Smalltalk class description, the implementation viewpoint, canbe made more concrete by performing the following two steps:

1. Deciding on a suitable representation for instances of the class.

2. Selecting and implementing efficient algorithms for the methods or operations.

When describing the representation, we must distinguish between instance variables and class variables. Instance variables are variables denoting the private data or state of an individual instance of a class. Class variables, on the other hand, are variables shared by all the instances of a class.

Suppose we have two instances of class Complex, referenced by variables complexl and complex2. What distinguishes them from one another? They both follow the same instance message protocol and thus can share a single copy of the method associated with each message. Instance methods, therefore, canbestored in the class description. However, complexl and complex2 must have their own private data - in particular, their individual

I'!II" I

real and imaginary parts. We speak of the real and imaginary parts as instance variables of the class Complex. That is, each instance of a class will have its own instance variables.

For example, if we send the message realPart to both complexl and complex2 as in complex1 realPert

complex2 realPert

we expect to obtain possibly different results because the method implementing the realPart message will extract independent values for the respective real components of complex1 and complex2.

Some variables can be shared by all the instances of a specific class. Such variables are called class variables. For example, Pi is a class variable representing the mathematical quantity 1t in class Float. Similarly, class Date contains class variables such as WeekDayNames - an array of symbols representing the days of the week (Monday, Tuesday, ), MontbNames - an array representing the months of the year (January, February, ), and DayslnMonth - an array containing the number of days in each month (31, 28, 31, ...).

2.5.4 Describing a Class

Smalltalk class descriptions consist of the following seven components:

class name A name that can be used to reference the class.

superclass name The name of the superclass (the role of superclasses will be discussed later in this chapter).

class variables Variables shared by all instances of the class.

instance variables Variables found in all instances of the class.

pool dictionaries The names of lists of shared variables that are to be accessible to the class and its instances (described in more detail later). Unlike class variables, the pools can be referenced by other unrelated classes.

class methods Operations that are understood by the class.

instance methods Operations that are understood by instances of the class.

Returning to our example, the class name is Complex, the superclass is class Object, and there are no class variables or pool dictionaries. In general, the choice of superclass is often critical to the implementation of a class, since it specifies what representation and methods may be inherited automatically from other classes. For the moment, we will ignore this issue and simply specify that the superclass of Complex is class Object. All Smallta1k classes, except Object itself, are ultimately subclasses of class Object.

Complex numbers can be represented in at least two ways - two independent floating point numbers or an array of two such numbers. As long as the choice does not impact the performance of the class, it doesn't matter which representation we choose - the external view presented to users of the class Complex is independent of the choice of representation.

Chapter 2 Smalltalk Fundamentals 43

We will choose two numbers to represent the real and imaginary parts respectively. Hence, each complex number has two instance variables, realPart and imaginaryPart.

The full description of class Complex is shown in Fig. 2.5. Programming in Smalltalk is carried out within an interactive program development environment. It is not normal, therefore, to add new classes to the system by compiling a file containing the complete class description.4 New classes are added to the Smalltalk system incrementally using a tool known as a Browser. The class definition is first entered and compiled into the system followed by the method definitions. Each method is compiled incrementally into the existing system and can immediately be tested. The system provides a template to guide the addition of new classes and methods. This process will be described in detail in succeeding chapters. For the time being, we will present the entire listing of the class definition.

Class Complex class name superclass name instance variable names class methods

instance creation

Complex Object

realPart imaginaryPart

newWithReal: realValue andlmaginary: imaginaryValue

"Returns an initialized instance of class Complex ."

I aComplex I

aComplex~Complex new.

aComplex realPart: realValue; imaginaryPart: imaginaryValue.

iaComplex examples

example

I complex1 complex2 I

complex1~Complex newWithReal: 2.5 andlmaginary: 3.1.

complex2~Complex newWithReal: -1.0 andImaginary: 0.5.

i complex1 *complex2.

"Complex example"

instance methods accessing

realPart

"Returns the real component of the receiver."

irealPart imaginaryPart

"Returns the imaginary component of the receiver."

iimaginaryPart

4This is often done, however, to add externally created classes to the system; for example, for porting code across machines - this operation is referred to as "filing in" a class definition.

1:1fll'i

reeiPert: reelValue

"Modifies the real component of the receiver to realValue."

realPart+- realValue imaginaryPart: imaginaryValue

"Modifies the imaginary component of the receiver to imaginaryValue."

imaginaryPart+- imaginaryValue arithmetic

+aComplex

"Returns an instance of class Complex equal to the sum of the receiver and the argument aComplex."

I realPartSum imaginaryPartSum I

realPartSum+-real Part+aComplexrealPart.

imaginaryPartSum+-imaginaryPart+aCompleximaginaryPart.

iComplexnawWithR.al:realPartSumandlmaginary:imaginaryPartSum

*&Complex

"Returns an instance of class Complex equal to the product of the receiver and the argument aComplex."

I realPartProduct imaginaryPartProduct I

realPartProduct+-(real Part*aComplexr.aIPart) -(imaginaryPart*aCompleximaginaryPartl.

imaginaryPartProduct+-IrealPart*aCompleximaginaryPart)+ (imaginaryPart*aComplexreaIPart).

iComplexn.wWithR.al:realPartProductandlmaginary:imaginaryPartProduct Figure 2.5 Class Complex.

Dans le document til Smalltalk (Page 56-61)