March 19, 2024

Objects and encapsulation continued

 

Encapsulation is sometimes described as "the packaging of data and the operations that act on that data". M206 presents this as the encapsulation of instance variables (the means by which an object can hold references to data values, or other objects) together with the methods that act on these instance variables. Encapsulation provides a conceptual barrier that prevents one object direct access to the instance variables held within another object.

The concept of objects fulfilling their responsibilities involves a carefully orchestrated process of message sending. When an object receives a message, it triggers a correspondingly named method; the code that is encapsulated in the object is executed. In doing so the object can carry out its required task. However, in order to perform its job, each object needs memory or state.

Smalltalk achieves this by using instance variables to hold references to other objects (the data values). An object can directly assign another object to one of its instance variables. It does this from within one of its own instance methods. However, encapsulation prevents any object from directly gaining access to another object's instance variables. To get an object to do anything, it must be sent a message, but although every object is encapsulated, it does not mean that all data and methods are hidden.

For example, the use of accessor messages can permit one object to gain access to another object's data. Getters and setters aid inheritance. They are an efficient means of writing code that can be reused by subclasses. If the getter returns a string this may cause problems with data integrity since Smalltalk strings are mutable. There is a solution that can be employed with Smalltalk to avoid the modification of a message answer, apart from a polite request not to by the programmer in the form of a method comment. A getter can be programmed to simply return a copy of the object referenced by an instance variable.

This process is unnecessary if the getter returns an immutable object, for example an integer. The additional messages involved with returning copies does incur an overhead that may be unacceptable if the speed of response is critical. The designer has to make a choice. What is more important, security or speed?

When should getters and setters be used? Certainly the benefits for inherited methods should be apparent. Reuse, write once and use many, saves work and reduces errors. If a method needs changing, then it is simply a case of modifying it in a single place; inheritance ensures that the changes are immediately available to any subclass.

But why reuse setters and getters within an instance method of the same class? Why not use direct assignment and avoid the use of self? One answer to this question would appear to depend on whether or not a setter method implements a value range, or some other Boolean condition that may be modified in the future. The simplest example of this is illustrated by the height instance variable of the HoverFrog class. The course team stipulated that this should range between 0 and 6. The reason for using the setter in some other method of the same class is linked to code maintenance. A change of required behaviour, say a requirement that height now reference a SmallInteger between 0 and 10, should be reflected in a modification to the setter. This would immediately be transmitted to any method that reuses it. No other maintenance is needed. Any method that employs direct assignment to set a value for the height instance variable, would not inherit this change of specified behaviour and consequently would also require modification. In this case a programmer will need to track down any such method and change the code by hand. Failure to do so will lead to inconsistent behaviour, or throw an error (see guide to using accessor messages).

With Smalltalk all data is private, although not necessarily hidden, and all methods, via an object's protocol, are public. The protocol, the interface of each object, allows access to all the methods of that object and the class browser ensures that nothing is hidden from the programmer. This flexibility and subsequent ease of use illustrates one good reason for Smalltalk being chosen to teach OOP.

Next page » OOP and Abstraction

Previous page « Objects and encapsulation

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Up to top of page