mirror of
https://github.com/EiffelSoftware/eiffel-org.git
synced 2025-12-07 15:22:31 +01:00
Author:halw
Date:2008-10-17T17:46:10.000000Z git-svn-id: https://svn.eiffel.com/eiffel-org/trunk@87 abb3cda0-5349-4a8f-a601-0c33ac3a8c38
This commit is contained in:
@@ -240,30 +240,30 @@ deposit_count: INTEGER
|
||||
end
|
||||
</code>
|
||||
|
||||
The value returned by any call will be the value of the expression <code>all_deposits.count</code> (to be explained in detail shortly) for that call, unless <code>all_deposits /code> is a <code>Void</code> reference ( <code>/=</code> means "not equal").
|
||||
The value returned by any call will be the value of the expression <code>all_deposits.count</code> (to be explained in detail shortly) for that call, unless <code>all_deposits</code> is a <code>Void</code> reference ( <code>/=</code> means "not equal").
|
||||
|
||||
The default initialization rules seen earlier for attributes (see the table above) also serve to initialize local entities and <code>Result</code> on routine entry. So in the last example, if <code>all_deposits</code> is void (as in the case on initialization with the class as given so far), <code>Result</code> keeps its default value of 0, which will be returned as the result of the function.
|
||||
|
||||
==Calls==
|
||||
|
||||
Apart from object creation, the basic computational mechanism, in the object-oriented style of computation represented by Eiffel, is feature call. In its basic form, it appears as
|
||||
<code>
|
||||
<code lang="text">
|
||||
target.feature (argument1, ...)
|
||||
</code>
|
||||
|
||||
where <code>target</code> is an entity or more generally an expression, <code>feature</code> is a feature name, and there may be zero or more <code>argument</code> expressions. In the absence of any <code>argument</code> the part in parentheses should be removed.
|
||||
where <code>target</code> is an entity or more generally an expression, <code lang="text">feature</code> is a feature name, and there may be zero or more <code>argument</code> expressions. In the absence of any <code>argument</code> the part in parentheses should be removed.
|
||||
|
||||
We have already seen such calls. If the <code>feature</code> denotes a procedure, the call is an instruction, as in
|
||||
We have already seen such calls. If the <code lang="text">feature</code> denotes a procedure, the call is an instruction, as in
|
||||
<code>
|
||||
all_deposits.extend (new)
|
||||
</code>
|
||||
|
||||
If <code>feature</code> denotes a query (function or attribute), the call is an expression, as in the right-hand side of
|
||||
If <code lang="text">feature</code> denotes a query (function or attribute), the call is an expression, as in the right-hand side of
|
||||
<code>
|
||||
Result := all_deposits.count
|
||||
</code>
|
||||
|
||||
Following the principle of Uniform Access (mentioned earlier in the section ''Objects, fields, values, and references''), this form is the same for calls to attributes and to functions without arguments. In this example, feature <code>count</code> from class <code>DEPOSIT_LIST</code> may indeed be implemented in either of these two ways: we can keep a <code>count /code> field in each list, updating it for each insertion and removal; or we can compute <code>count</code>, whenever requested, by traversing the list and counting the number of items.
|
||||
Following the principle of Uniform Access (mentioned earlier in the section ''Objects, fields, values, and references''), this form is the same for calls to attributes and to functions without arguments. In this example, feature <code>count</code> from class <code>DEPOSIT_LIST</code> may indeed be implemented in either of these two ways: we can keep a <code>count </code> field in each list, updating it for each insertion and removal; or we can compute <code>count</code>, whenever requested, by traversing the list and counting the number of items.
|
||||
|
||||
In the case of a routine with arguments -- procedure or function -- the routine will be declared, in its class, as
|
||||
<code>
|
||||
@@ -291,7 +291,7 @@ infix "+" (other: INTEGER): INTEGER
|
||||
|
||||
Such a feature has all the properties and prerogatives of a normal "identifier" feature, except for the form of the calls, which is infix, as in <code>i + j</code> , rather than using dot notation. An infix feature must be a function, and take exactly one argument. Similarly, a function can be declared as <code>prefix "-" </code>, with no argument, permitting calls of the form <code> -3 </code> rather than <code>(3).negated</code> .
|
||||
|
||||
Predefined library classes covering basic types such as <code>INTEGER</code>, <code>CHARACTER</code>, <code>BOOLEAN</code>, <code>REAL</code>, <code>DOUBLE</code> are known to the Eiffel compiler, so that a call of the form <code j + i</code>, although conceptually equivalent to a routine call, can be processed just as efficiently as the corresponding arithmetic expression in an ordinary programming language. This brings the best of both worlds: conceptual simplicity, enabling Eiffel developers, when they want to, to think of integers and the like as objects; and efficiency as good as in lower-level approaches.
|
||||
Predefined library classes covering basic types such as <code>INTEGER</code>, <code>CHARACTER</code>, <code>BOOLEAN</code>, <code>REAL</code>, <code>DOUBLE</code> are known to the Eiffel compiler, so that a call of the form <code>j + i</code>, although conceptually equivalent to a routine call, can be processed just as efficiently as the corresponding arithmetic expression in an ordinary programming language. This brings the best of both worlds: conceptual simplicity, enabling Eiffel developers, when they want to, to think of integers and the like as objects; and efficiency as good as in lower-level approaches.
|
||||
|
||||
Infix and prefix features are available to any class, not just the basic types' predefined classes. For example a graphics class could use the name <code>infix "|-|"</code> for a function computing the distance between two points, to be used in expressions such as <code>point1 |-| point2</code> .
|
||||
|
||||
@@ -385,7 +385,7 @@ This example also illustrates that the distinction between expanded and referenc
|
||||
|
||||
==Basic operations==
|
||||
|
||||
To assign, copy and compare values, you can rely on a number of mechanisms. Two of them, assignment and equality testing, are language constructs; the others are library features, coming from the top-level class <code>ANY</code> seen earlier (page [[5 The Static Picture: System Organization|15]] ).
|
||||
To assign, copy and compare values, you can rely on a number of mechanisms. Two of them, assignment and equality testing, are language constructs; the others are library features, coming from the top-level class <code>ANY</code> seen earlier.
|
||||
|
||||
Assignment uses the symbol <code> := </code>. The assignment instruction
|
||||
<code>
|
||||
@@ -404,7 +404,7 @@ For entities of reference types, the value of <code>x</code> will be a void refe
|
||||
[[Image:tutorial-9]]
|
||||
|
||||
|
||||
For entities of expanded types, the values are objects; the object attached to <code>x</code> will be overwritten with the contents of the object attached to <code y</code>. In the case of atomic objects, as in <code>n := 3</code> with the declaration <code> n: INTEGER</code> , this has the expected effect of assigning to <code>n</code> the integer value <code>3</code>; in the case of composite objects, this overwrites the fields for <code>x</code>, one by one, with the corresponding <code>y</code> fields.
|
||||
For entities of expanded types, the values are objects; the object attached to <code>x</code> will be overwritten with the contents of the object attached to <code>y</code>. In the case of atomic objects, as in <code>n := 3</code> with the declaration <code> n: INTEGER</code> , this has the expected effect of assigning to <code>n</code> the integer value <code>3</code>; in the case of composite objects, this overwrites the fields for <code>x</code>, one by one, with the corresponding <code>y</code> fields.
|
||||
|
||||
To copy an object, use <code>x.copy (y)</code> which assumes that both <code>x</code> and <code>y</code> are non-void, and copies the contents of <code>y</code>'s attached object onto those of <code>x</code>'s. For expanded entities the effect is the same as that the of the assignment <code>x := y</code>.
|
||||
|
||||
@@ -473,12 +473,12 @@ The Eiffel Software's implementation of Eiffel provides a sophisticated '''garba
|
||||
|
||||
==Information hiding and the call rule==
|
||||
|
||||
The basic form of computation, it has been noted, is a call of the form <code>target.feature (...)</code> . This is only meaningful if <code>feature</code> denotes a feature of the generating class of the object to which <code>target</code> (assumed to be non-void) is attached. The precise rule is the following:
|
||||
The basic form of computation, it has been noted, is a call of the form <code lang="text">target.feature (...)</code> . This is only meaningful if <code lang="text">feature</code> denotes a feature of the generating class of the object to which <code>target</code> (assumed to be non-void) is attached. The precise rule is the following:
|
||||
|
||||
{{rule|name=Feature Call|text=A call of the form <code>target.feature (...)</code> appearing in a class C is only valid if feature is a feature of the base class of target 's type, and is available to C.}}
|
||||
{{rule|name=Feature Call|text=A call of the form <code lang="text">target.feature (...)</code> appearing in a class C is only valid if <code lang="text">feature</code> is a feature of the base class of <code>target</code>'s type, and is available to C.}}
|
||||
|
||||
|
||||
The first condition simply expresses that if <code>target</code> has been declared as <code>target: A</code> then <code>feature</code> must be the name of one of the features of <code>A</code>. The second condition reflects Eiffel's application of the principles of information hiding. A <code>feature</code> clause, introducing one or more feature declarations, may appear not only as
|
||||
The first condition simply expresses that if <code>target</code> has been declared as <code>target: A</code> then <code lang="text">feature</code> must be the name of one of the features of <code>A</code>. The second condition reflects Eiffel's application of the principles of information hiding. A <code>feature</code> clause, introducing one or more feature declarations, may appear not only as
|
||||
<code>
|
||||
feature -- Comment identifying the feature category
|
||||
|
||||
@@ -587,11 +587,11 @@ The levels of privilege available to the class author include, for any field:
|
||||
* Export it for free read and write by any client, by also exporting a procedure of the <code>set_attribute</code> kind.
|
||||
* Export it in '''restricted-write''' mode, by exporting a procedure such as <code>deposit</code> of class <code>ACCOUNT</code>, which adds a specified amount to the <code>balance</code> field, rather than directly setting the balance.
|
||||
|
||||
The last case is particularly interesting is that it allows the class designer to set the precise way in which clients will manipulate the class instances, respecting the properties of the class and its integrity. The exported routines may, through the Design by Contract mechanism reviewed later ( [[8 Design by Contract (tm), Assertions and Exceptions|8]] ), place some further restrictions on the permitted modifications, for example by requiring the withdrawn amount to be positive.
|
||||
The last case is particularly interesting is that it allows the class designer to set the precise way in which clients will manipulate the class instances, respecting the properties of the class and its integrity. The exported routines may, through the Design by Contract mechanism reviewed later in ( [[8 Design by Contract (tm), Assertions and Exceptions]] ), place some further restrictions on the permitted modifications, for example by requiring the withdrawn amount to be positive.
|
||||
|
||||
These rules follow directly from the more general goals (reusability, extendibility, reliability) and principles (Uniform Access, information hiding) underlying Eiffel software design. They reflect a view that each class must denote a well-understood abstraction, defined by a set of exported features chosen by the class designer -- the "control panel".
|
||||
|
||||
The class documentation (the contract form, see page [[8 Design by Contract (tm), Assertions and Exceptions|44]] ) makes this view clear to client authors; no violation of that interface is permitted. This approach also paves the way for future '''generalization''' -- the final step of the cluster lifecycle, seen earlier on page [[3 The Software Process in Eiffel|9]] -- of the most promising components, and their inclusion into reusable libraries.
|
||||
The class documentation (see [[8 Design by Contract (tm), Assertions and Exceptions#The_contract_form_of_a_class|the contract form of a class]] ) makes this view clear to client authors; no violation of that interface is permitted. This approach also paves the way for future '''generalization''' -- the final step of the cluster lifecycle, seen earlier in the section [[3 The Software Process in Eiffel#Generalization_and_reuse|Generalization and reuse]] -- of the most promising components, and their inclusion into reusable libraries.
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user