mirror of
https://github.com/EiffelSoftware/eiffel-org.git
synced 2026-04-04 17:19:23 +02:00
Author:halw
Date:2008-10-22T21:23:04.000000Z git-svn-id: https://svn.eiffel.com/eiffel-org/trunk@94 abb3cda0-5349-4a8f-a601-0c33ac3a8c38
This commit is contained in:
@@ -20,19 +20,20 @@ The term "entity" generalizes the more common notion of "variable". An entity de
|
||||
An entity is said to be void if it is not attached to any object. By default, entities are void at initialization. To obtain objects at run-time, a routine <code>r</code> appearing in the client class <code>X</code> may use a '''creation instruction''' of the form
|
||||
|
||||
<code>
|
||||
create acc</code>
|
||||
create acc</code>
|
||||
|
||||
|
||||
which creates a new direct instance of <code> ACCOUNT</code>, attaches <code>acc</code> to that instance, and initializes all its fields to default values. A variant of this notation, studied below, makes it possible to override the default initializations.
|
||||
|
||||
Once the client has attached <code>acc</code> to an object, it may call on this object the features defined in class <code>ACCOUNT</code>. Here is an extract with some feature calls using <code>acc</code> as their target:
|
||||
<code>
|
||||
acc.open ("Jill")
|
||||
acc.deposit (5000)
|
||||
if acc.may_withdraw (3000) then
|
||||
acc.withdraw (3000)
|
||||
print (acc.balance)
|
||||
end</code>
|
||||
acc.open ("Jill")
|
||||
acc.deposit (5000)
|
||||
if acc.may_withdraw (3000) then
|
||||
acc.withdraw (3000)
|
||||
print (acc.balance)
|
||||
end
|
||||
</code>
|
||||
|
||||
These feature calls use dot notation, of the form <code>target_name.feature_name</code>, possibly followed by a list of arguments in parentheses. Features are of two kinds:
|
||||
* '''Routines''', such as <code>open</code>, <code>deposit</code>, <code>may_withdraw</code>, <code>withdraw</code>, represent computations applicable to instances of the class.
|
||||
@@ -44,47 +45,48 @@ Routines are further divided into '''procedures''' (commands, which do not retur
|
||||
|
||||
In class <code>ACCOUNT</code>, is feature <code>balance</code> an attribute, or is it a function with no argument? The above extract of the client class <code>X</code> doesn't say, and this ambiguity is intentional. A client of <code>ACCOUNT</code> must not need to know how class <code>ACCOUNT</code> delivers an account's balance when requested: by looking up a field present in each account object, or by calling a function that computes the balance from other fields. Choosing between these techniques is the business of class <code>ACCOUNT</code>, not anybody else's. Because such implementation choices are often changed over the lifetime of a project, it is essential to protect clients against their effects. This is known as the '''Uniform Access Principle''', stating that the choice between representing a property through memory (an attribute) or through an algorithm (function) shall not affect how clients use it.
|
||||
|
||||
So much for how client classes will typically use <code>ACCOUNT. </code> Below is a first sketch of how class <code>ACCOUNT</code> itself might look. Line segments beginning with <code>--</code> are comments. The class includes two <code>feature</code> clauses, introducing its features. The first begins with just the keyword <code>feature</code>, without further qualification; this means that the features declared in this clause are available (or "exported") to all clients of the class. The second clause is introduced by <code>feature</code> { <code>NONE</code>} to indicate that the feature that follows, called <code>add</code>, is available to no client. What appears between the braces is a list of client classes to which the corresponding features are available; <code>NONE</code> is a special class of the Kernel Library, which has no instances, so that <code>add</code> is in effect a secret feature, available only locally to the other routines of class <code>ACCOUNT</code>. So in a client class such as <code>X</code>, the call <code>acc.add ( -3000 )</code> would be invalid.
|
||||
So much for how client classes will typically use <code>ACCOUNT. </code> Below is a first sketch of how class <code>ACCOUNT</code> itself might look. Line segments beginning with <code>--</code> are comments. The class includes two <code>feature</code> clauses, introducing its features. The first begins with just the keyword <code>feature</code>, without further qualification; this means that the features declared in this clause are available (or "exported") to all clients of the class. The second clause is introduced by <code>feature {NONE}</code> to indicate that the feature that follows, called <code>add</code>, is available to no client. What appears between the braces is a list of client classes to which the corresponding features are available; <code>NONE</code> is a special class of the Kernel Library, which has no instances, so that <code>add</code> is in effect a secret feature, available only locally to the other routines of class <code>ACCOUNT</code>. So in a client class such as <code>X</code>, the call <code>acc.add ( -3000 )</code> would be invalid.
|
||||
<code>
|
||||
class ACCOUNT
|
||||
class
|
||||
ACCOUNT
|
||||
|
||||
feature
|
||||
|
||||
balance: INTEGER
|
||||
owner: PERSON
|
||||
minimum_balance: INTEGER = 1000
|
||||
balance: INTEGER
|
||||
owner: PERSON
|
||||
minimum_balance: INTEGER = 1000
|
||||
|
||||
open (who: PERSON)
|
||||
-- Assign the account to owner who.
|
||||
do
|
||||
owner := who
|
||||
end
|
||||
open (who: PERSON)
|
||||
-- Assign the account to owner who.
|
||||
do
|
||||
owner := who
|
||||
end
|
||||
|
||||
deposit (sum: INTEGER)
|
||||
-- Deposit sum into the account.
|
||||
do
|
||||
add (sum)
|
||||
end
|
||||
deposit (sum: INTEGER)
|
||||
-- Deposit sum into the account.
|
||||
do
|
||||
add (sum)
|
||||
end
|
||||
|
||||
withdraw (sum: INTEGER)
|
||||
-- Withdraw sum from the account.
|
||||
do
|
||||
add (-sum)
|
||||
end
|
||||
withdraw (sum: INTEGER)
|
||||
-- Withdraw sum from the account.
|
||||
do
|
||||
add (-sum)
|
||||
end
|
||||
|
||||
may_withdraw (sum: INTEGER): BOOLEAN
|
||||
-- Is there enough money to withdraw sum?
|
||||
do
|
||||
Result := (balance >= sum + minimum_balance)
|
||||
end
|
||||
may_withdraw (sum: INTEGER): BOOLEAN
|
||||
-- Is there enough money to withdraw sum?
|
||||
do
|
||||
Result := (balance >= sum + minimum_balance)
|
||||
end
|
||||
|
||||
feature {NONE}
|
||||
|
||||
add (sum: INTEGER)
|
||||
-- Add sum to the balance
|
||||
do
|
||||
balance := balance + sum
|
||||
end
|
||||
add (sum: INTEGER)
|
||||
-- Add sum to the balance
|
||||
do
|
||||
balance := balance + sum
|
||||
end
|
||||
|
||||
end -- ACCOUNT
|
||||
</code>
|
||||
@@ -93,7 +95,7 @@ Let us examine the features in sequence. The <code>do</code> <code>...</code> <c
|
||||
|
||||
The language definition guarantees automatic initialization, so that the initial balance of an account object will be zero after a creation instruction. Each type has a default initial value: zero for <code>INTEGER</code> and <code>REAL</code>, false for <code>BOOLEAN</code>, null character for <code>CHARACTER</code>, and a void reference for reference types. The class designer may also provide clients with different initialization options, as will be seen below in a revised version of this example.
|
||||
|
||||
The other public features, <code>withdraw deposit, open,</code> and <code>may_withdraw</code> are straight-forward routines. The special entity <code>Result</code>, used in <code>may_withdraw</code>, denotes the function result; it is initialized on function entry to the default value of the function's result type. You may only use <code>Result</code> in functions.
|
||||
The other public features, <code>withdraw, deposit, open,</code> and <code>may_withdraw</code> are straight-forward routines. The special entity <code>Result</code>, used in <code>may_withdraw</code>, denotes the function result; it is initialized on function entry to the default value of the function's result type. You may only use <code>Result</code> in functions.
|
||||
|
||||
The secret procedure <code>add</code> serves for the implementation of the public procedures <code>deposit</code> and <code>withdraw</code>; the designer of <code>ACCOUNT</code> judged it too general to be exported by itself. The clause "<code>= 1000</code>" introduces <code>minimum_balance</code> as a constant attribute, which will not occupy any space in instances of the class; in contrast, every instance has a field for every non-constant attribute such as <code>balance</code>.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user