Top Banner
More About Classes Ranga Rodrigo
39

More About Classes Ranga Rodrigo. Information hiding. Copying objects.

Jan 02, 2016

Download

Documents

Garry Baldwin
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: More About Classes Ranga Rodrigo. Information hiding. Copying objects.

More About Classes

Ranga Rodrigo

Page 2: More About Classes Ranga Rodrigo. Information hiding. Copying objects.

Information hiding.

Copying objects.

Page 3: More About Classes Ranga Rodrigo. Information hiding. Copying objects.

Eiffel class types are reference types.

Page 4: More About Classes Ranga Rodrigo. Information hiding. Copying objects.

Unexpected Phenomena Due to Reference Types

read_name is local first_name, last_name : STRING do io.read_string first_name := io.last_string io.read_string last_name := io.last_string io.put_string(first_name + " " +

last_name + "%N") end

Page 5: More About Classes Ranga Rodrigo. Information hiding. Copying objects.

Issues like this arise particularly when data values are tested for equality or copied.

All languages provide built-in facilities for assignment and testing equality, in Eiffel using the symbols "=", "/=" and ":=".

These operations work on values.

Page 6: More About Classes Ranga Rodrigo. Information hiding. Copying objects.

References In languages like Java and Eiffel, where

class variables hold references, the operations work on the reference values. In Eiffel: Assignment of class variables b := c copies a

reference value, so b and c refer to the same object.

Equality and inequality tests on class variables b = c and b /= c compare reference values, and report on whether b and c refer to the same object.

Page 7: More About Classes Ranga Rodrigo. Information hiding. Copying objects.

In Eiffel

Assignment of class variables b := c copies a reference value, so b and c refer to the same object.

Equality and inequality tests on class variables b = c and b /= c compare reference values, and report on whether b and c refer to the same object.

Page 8: More About Classes Ranga Rodrigo. Information hiding. Copying objects.

Providing Value-Semantics

Often, however, we want "value" semantics even with reference variables.

To provide this, features can be defined in the root class of a language's class hierarchy which can be overidden in user-defined classes to provide the required functionality.

In Java, this root class is called "Object" and in Eiffel "ANY".

It is assumed that every other class defined in the language automatically inherits from the root class, even if this is not stated in the class definition.

Page 9: More About Classes Ranga Rodrigo. Information hiding. Copying objects.

Equality

Two objects can be tested for equality using the following two features, defined in ANY:

b.is_equal(c)equal(b, c)

These features compare objects on a field by field basis, and return true if all attributes are the same in both objects, in the sense of b.field = c.field. equal(b, c) will work even if b = Void, so is often less cumbersome to use than b.is_equal(c), where you should check for this case, or else risk a run-time exception.

Page 10: More About Classes Ranga Rodrigo. Information hiding. Copying objects.

Equality

Philosophically speaking, this is an odd sense of equality.

Normally we assume that if two objects are equal, they can be substituted for each other in any context without problem.

This is not guaranteed by equal, however. Consider a POINT class, with two coordinate

attributes, and a LINE class, with two POINT attributes. Then look at the following code:

Page 11: More About Classes Ranga Rodrigo. Information hiding. Copying objects.

origin, p1, p2 : POINTl1, l2 : LINE

create origin.make(0, 0)create p1.make(1, 1)create p2.make(1, 1)

create l1.make(origin, p1)create l2.make(origin, p2)

equal(p1, p2) -- is True, butequal(l1, l2) -- is False

Page 12: More About Classes Ranga Rodrigo. Information hiding. Copying objects.

Equality

This seems to be a translation into Eiffel of the assertion "two distinct lines can be drawn from the origin to a given point", which is probably not true of the domain being modelled by the POINT and LINE classes.

The problem here is that equal only tests for equality of the first-level attributes within two objects.

Page 13: More About Classes Ranga Rodrigo. Information hiding. Copying objects.

Deep Equality

If these attributes hold references, we might want to check whether their attributes are in turn equal, rather than just seeing if they are the same object.

Eiffel has a notion of deep equality which does this. Using the definitions above:

deep_equal(l1, l2) -- is True

Page 14: More About Classes Ranga Rodrigo. Information hiding. Copying objects.

Deep Equality

For some reason, there is no corresponding feature b.is_deep_equal(c).

Rather than using the notion of deep equality, a simpler approach is to explicitly define a suitable equality test for each class.

This is done by redefining the feature is_equal. (The syntax for inheritance shown here will be explained in the next lecture.)

Page 15: More About Classes Ranga Rodrigo. Information hiding. Copying objects.

class LINEinherit ANY redefine

is_equal endfeature p1, p2 : POINT

is_equal( l : LINE ) : BOOLEAN isdo

Result := equal(p1, l.p1) andequal(p2, l.p2)

endend

Page 16: More About Classes Ranga Rodrigo. Information hiding. Copying objects.

Object Copying

Objects can be copied using a feature copy, overwrites the field values in one object by those of another, or clone which returns a new object which is a copy of another.

Shallow copying can lead to multiple references to shared objects, so deep equivalents of these features also exist.

The syntax is:

c.copy(b) c := clone(b)c.deep_copy(b) c := deep_clone(b)

Page 17: More About Classes Ranga Rodrigo. Information hiding. Copying objects.

Object Copying

Notice that, if no redefinitions are in effect, two objects will be equal after a copy, and deep_equal after a deep_copy.

A class-specific copy function can be obtained by redefining the copy feature inherited from ANY.

Page 18: More About Classes Ranga Rodrigo. Information hiding. Copying objects.

We must limitthe access that client

code has to theinternal details of

a class.

Page 19: More About Classes Ranga Rodrigo. Information hiding. Copying objects.

Information Hiding

Information hiding is a technique to limit the access that client code has to the internal details of a class.

Benefits of this include: protection against unintended corruption of

class data stored in attributes; ability to modify the internal details of a

class without affecting client code (provided that the class interface is kept constant).

Page 20: More About Classes Ranga Rodrigo. Information hiding. Copying objects.

Information Hiding in Java and C++

Java and C++ provide mechanisms for defining client access to class features: public, private etc.

A class will typically support information hiding by making its attributes private, and providing a public interface.

Page 21: More About Classes Ranga Rodrigo. Information hiding. Copying objects.

Information Hiding in Eiffel

In Eiffel, the Uniform Access Principle and the fact the clients have read-only access to class attributes make this approach unnecessary in simple cases. In general, however, an information hiding mechanism is needed.

E.g., the RESULTS class defined in the last lecture: Eiffel does not prevent client code from changing the values in the array that records the points gained for the each game:

r : RESULTSr.points[2] := 3

Page 22: More About Classes Ranga Rodrigo. Information hiding. Copying objects.

class RESULTScreate makefeature points : ARRAY[INTEGER] played : INTEGER total : INTEGER make( games : INTEGER ) is

do create points.make(1, games)

end add_result( pts : INTEGER ) is

do played := played + 1 points.put( pts, played ) total := total + pts

endend

Page 23: More About Classes Ranga Rodrigo. Information hiding. Copying objects.

Information Hiding in Eiffel

The mechanism for supporting information hiding in Eiffel is to specify which classes have access to a given feature or features. The points array can be made private as follows:

feature {} -- empty list of clients, so private points : ARRAY[INTEGER]

Page 24: More About Classes Ranga Rodrigo. Information hiding. Copying objects.

Information Hiding in Eiffel

class RESULTSfeature {} -- empty list of clients, so private points : ARRAY[INTEGER]feature -- the default is public played : INTEGER total : INTEGER ...end

Page 25: More About Classes Ranga Rodrigo. Information hiding. Copying objects.

Information Hiding in Eiffel

In C++ and Java, a class instance has access to the private data members of all other instances of the class.

In Eiffel, however, this is not the case: Given the class declaration above, the

following code will not compile because the current instance of the class does not have access the the private features of the parameter r, even though it is an instance of the same class.

Page 26: More About Classes Ranga Rodrigo. Information hiding. Copying objects.

Information Hiding in Eiffel

class RESULTS ... compare( r : RESULTS ) is

do if r.points[0] > points[0] then

io .put_string("They did better.")

endend

end

points arrayof r

points arrayof this instance

Page 27: More About Classes Ranga Rodrigo. Information hiding. Copying objects.

Information Hiding in Eiffel

In a way this is logical: the declaration feature {} says "no class has access to this feature", i.e., not even other instances of the same class.

To make this example work, you must explicitly grant this access:

class RESULTS

feature {RESULTS} points : ARRAY[INTEGER] ...

end

Page 28: More About Classes Ranga Rodrigo. Information hiding. Copying objects.

Information Hiding in Eiffel

An alternative approach would be to leave the original access level but provide an access function get_points to use where direct access to the array is blocked.

An argument can be made that this is preferable, as it isolates direct access of the array data structure to one place; if this data structure was subsequently changed, it would be simpler to update the class if only one function made use of it.

Page 29: More About Classes Ranga Rodrigo. Information hiding. Copying objects.

Information Hiding in Eiffel

Information hiding is in general provided in Eiffel by specifying in a feature clause all the classes that have access to the features in that clause.

In fact, access is granted not only to the named class, but also to all of its subclasses.

Page 30: More About Classes Ranga Rodrigo. Information hiding. Copying objects.

Information Hiding in Eiffel

To give all classes access to a feature you can write:

because all classes are descendants of the root class ANY.

This is the default case, and is the equivalent of public in C++ and Java.

feature {ANY}

Page 31: More About Classes Ranga Rodrigo. Information hiding. Copying objects.

Information Hiding in Eiffel

A declaration like

gives access not only to the results class but also all of its subclasses. In other words, this is similar to defining the feature to be protected, in C++ and Java.

feature {RESULTS}

Page 32: More About Classes Ranga Rodrigo. Information hiding. Copying objects.

Information Hiding in Eiffel: Summary

feature speed :

DOUBLE

Read only access to clients. No write access.

feature {} speed :

DOUBLE

No access to clients,including the instances of

the same class.

feature {CAR} speed :

DOUBLE

No access except to CAR and its

descendants (protected).feature {ANY}

speed : DOUBLE

Access to all the classes(public).

Page 33: More About Classes Ranga Rodrigo. Information hiding. Copying objects.

Information Hiding and DBC

A routine's pre and postcondition form a contract between the writer of the routine and its client.

It seems logical then that features that are mentioned in a routine's specification should be accessible to potential clients of the routines; otherwise, the client would be in the position of not being able to examine the contract.

Eiffel enforces this requirement for preconditions. In the RESULTS class, the following code will not compile:

Page 34: More About Classes Ranga Rodrigo. Information hiding. Copying objects.

Information Hiding and Preconditions

add_result( pts : INTEGER ) is require points[played + 1] = 0 do

played := played + 1points.put( pts, played )total := total + pts

end

points arraynot accessible to

clients

Page 35: More About Classes Ranga Rodrigo. Information hiding. Copying objects.

Information Hiding and Preconditions

In the previous example, precondition is not accessible to the client, who is therefore unable to check that the precondition is satisfied before calling the routine.

One way round this, if it is a problem, is do define an accessor function which returns the data necessary to write the precondition.

Page 36: More About Classes Ranga Rodrigo. Information hiding. Copying objects.

Information Hiding and Post-conditions

The situation with postconditions is slightly different.

Postconditions can mention private features, as the effect of a routine on such features can be a crucial part of the routine's specification:

Page 37: More About Classes Ranga Rodrigo. Information hiding. Copying objects.

Information Hiding and Preconditions

add_result( pts : INTEGER ) is do

played := played + 1points.put( pts, played )total := total + pts

ensure points[played] = pts end

points arrayis accessible to post-condition

Page 38: More About Classes Ranga Rodrigo. Information hiding. Copying objects.

Information Hiding and Post-Conditions

A postcondition mentioning a private feature is considered to be a private postcondition, however, and not part of the routine's contract.

Warning: it is sometimes stated that private postconditions do not appear in the interface view of a class, but this is not consistently supported by EiffelStudio.

Class invariants are not affected by the access level of features, as invariants are not accessible to the clients of a class.

Page 39: More About Classes Ranga Rodrigo. Information hiding. Copying objects.

Abstract Classes

These are called deferred in Eiffel. Both the class and any abstract features

must be explicitly declared to be deferred. As in other languages, base classes in

hierarchies are often abstract.