Presentation is loading. Please wait.

Presentation is loading. Please wait.

More About Classes Ranga Rodrigo. Quiz: Question 1 Write the following C++ code in Eiffel. void covert { int i ; float f(1.41) ; i = (int) f ; }

Similar presentations


Presentation on theme: "More About Classes Ranga Rodrigo. Quiz: Question 1 Write the following C++ code in Eiffel. void covert { int i ; float f(1.41) ; i = (int) f ; }"— Presentation transcript:

1 More About Classes Ranga Rodrigo

2 Quiz: Question 1 Write the following C++ code in Eiffel. void covert { int i ; float f(1.41) ; i = (int) f ; }

3 Quiz: Question 2 A class that represents a course in shown in the following slide. Add procedure to display all the grades. Add a class invariant to ensure that each of the grades is between 0 and 100 (inclusive).

4 class COURSE create make feature grades : ARRAY[INTEGER] max_students : INTEGER is 10 make is do create grades.make(1,max_students) end

5 Quiz: Question 3 What is a typed language? What is an untyped language? Categorize languages in terms of typing. Give examples. What is a type-secure language? Give and example of weak typing existing in C.

6 Solution: Question 1 void covert { int i; float f(1.41); i = (int)f; } convert is local i : INTEGER f : REAL do f := 1.41 i := f.floor end 1 mark 2 marks Total 5 marks

7 Solution: Question 2

8 class COURSE create make feature grades : ARRAY[INTEGER] max_students : INTEGER is 10 make is -- Constructor do create grades.make(1,max_students) end

9 display is -- Displays all the grades local i : INTEGER do from i := grades.lower until i > grades.upper loop io.put_integer (grades.item (i)) io.new_line i := i + 1 end 1 mark

10 invariant valid_grades: grades.for_all( (agent (i : INTEGER) : BOOLEAN do Result := 0 <= i and i <= 100 end ) end 1 mark 2 marks 1 mark Total 10 marks

11 Solution: Question 3 What is a typed language? Typed languages try to use the compiler to detect type errors. This is to ensure that programs will not crash at run-time. This is widely seen as a crucial aspect of language security. What is an untyped language? Variables do not have a type. Programmers have to keep track of what is stored where. Errors may only be caught at run-time, when it may be too late. Worse, data corruption may take place unnoticed. 2 marks

12 Languages Untyped Typed Strongly Weakly Pascal Eiffel C Perl Categorize languages in terms of typing. Give examples. 2 marks

13 Solution: Question 3 What is a type-secure language? A type-secure language is one which would in no circumstances give rise to a run-time error related to types. It is hard to guarantee this property. Give and example of weak typing existing in C. The distinction relates to the extent to which the compiler will silently convert data of one type to another related type. E.g., converting numeric types, or integers to addresses in C. Total 10 marks 2 marks

14 Information hiding. Copying objects.

15 Eiffel class types are reference types. reference types.

16 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

17 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.

18 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.

19 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.

20 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.

21 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.

22 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:

23 origin, p1, p2 : POINT l1, 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, but equal(l1, l2) -- is False

24 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.

25 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

26 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.)

27 class LINE inherit ANY redefine is_equal end feature p1, p2 : POINT is_equal( l : LINE ) : BOOLEAN is do Result := equal(p1, l.p1) and equal(p2, l.p2) end

28 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)

29 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.

30 We must limit the access that client code has to the internal details of a class.

31 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).

32 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.

33 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 : RESULTS r.points[2] := 3

34 class RESULTS create make feature 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 end

35 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]

36 Information Hiding in Eiffel class RESULTS feature {} -- empty list of clients, so private points : ARRAY[INTEGER] feature -- the default is public played : INTEGER total : INTEGER... end

37 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.

38 Information Hiding in Eiffel class RESULTS... compare( r : RESULTS ) is do if r.points[0] > points[0] then io.put_string("They did better.") end points array of r points array of this instance

39 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

40 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.

41 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.

42 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}

43 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}

44 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).

45 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:

46 Information Hiding and Preconditions add_result( pts : INTEGER ) is require points[played + 1] = 0 do played := played + 1 points.put( pts, played ) total := total + pts end points array not accessible to clients

47 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.

48 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:

49 Information Hiding and Preconditions add_result( pts : INTEGER ) is do played := played + 1 points.put( pts, played ) total := total + pts ensure points[played] = pts end points array is accessible to post-condition

50 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.

51 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.


Download ppt "More About Classes Ranga Rodrigo. Quiz: Question 1 Write the following C++ code in Eiffel. void covert { int i ; float f(1.41) ; i = (int) f ; }"

Similar presentations


Ads by Google