Author:halw

Date:2008-10-17T21:31:06.000000Z


git-svn-id: https://svn.eiffel.com/eiffel-org/trunk@88 abb3cda0-5349-4a8f-a601-0c33ac3a8c38
This commit is contained in:
halw
2008-10-17 21:31:06 +00:00
parent 413e4cbbec
commit c7f9d0c5e2
5 changed files with 95 additions and 65 deletions

View File

@@ -12,42 +12,42 @@ An Eiffel system is a collection of classes, one of which is designated as the r
To execute such a system is to create an instance of the root class (an object created according to the class description) and to execute the root procedure. In anything more significant than "Hello World" systems, this will create new objects and apply features to them, in turn triggering further creations and feature calls.
For the system to make sense, it must contains all the classes on which the root '''depends''' directly or indirectly. A class <code> B </code> depends on a class <code> A </code> if it is either a '''client''' of <code> A </code>, that is to say uses objects of type <code> A </code>, or an '''heir''' of <code> A </code>, that is to say extends or specializes <code> A </code>. (These two relations, client and inheritance, are covered below.)
For the system to make sense, it must contains all the classes on which the root '''depends''' directly or indirectly. A class <code>B</code> depends on a class <code>A</code> if it is either a '''client''' of <code>A</code>, that is to say uses objects of type <code>A</code>, or an '''heir''' of <code>A</code>, that is to say extends or specializes <code>A</code>. (These two relations, client and inheritance, are covered below.)
==Classes==
The notion of class is central to the Eiffel approach. A class is the description of a type of run-time data structures (objects), characterized by common operations features) and properties. Examples of classes include:
* In a banking system, a class <code> ACCOUNT </code> may have features such as <code> deposit </code>, adding a certain amount to an account, <code> all_deposits </code>, yielding the list of deposits since the account's opening, and <code> balance </code>, yielding the current balance, with properties stating that <code> deposit </code> must add an element to the <code> all_deposits </code> list and update <code> balance </code> by adding the sum deposited, and that the current value of <code> balance </code> must be consistent with the lists of deposits and withdrawals.
* A class <code> COMMAND </code> in an interactive system of any kind may have features such as <code> execute </code> and <code> undo </code> , as well as a feature <code> undoable </code> which indicates whether a command can be undone, with the property that <code> undo </code> is only applicable if <code> undoable </code> yields the value true.
* A class <code> LINKED_LIST </code> may have features such as <code> put </code>, which adds an element to a list, and <code> count </code>, yielding the number of elements in the list, with properties stating that <code> put </code> increases <code> count </code> by one and that <code> count </code> is always non-negative.
* In a banking system, a class <code>ACCOUNT</code> may have features such as <code>deposit</code>, adding a certain amount to an account, <code>all_deposits</code>, yielding the list of deposits since the account's opening, and <code>balance</code>, yielding the current balance, with properties stating that <code>deposit</code> must add an element to the <code>all_deposits</code> list and update <code>balance</code> by adding the sum deposited, and that the current value of <code>balance</code> must be consistent with the lists of deposits and withdrawals.
* A class <code>COMMAND</code> in an interactive system of any kind may have features such as <code>execute</code> and <code>undo</code> , as well as a feature <code>undoable</code> which indicates whether a command can be undone, with the property that <code>undo</code> is only applicable if <code>undoable</code> yields the value true.
* A class <code>LINKED_LIST</code> may have features such as <code>put</code>, which adds an element to a list, and <code>count</code>, yielding the number of elements in the list, with properties stating that <code>put</code> increases <code>count</code> by one and that <code>count</code> is always non-negative.
We may characterize the first of these examples as an analysis class, directly modeling objects from the application domain; the second one as a design class, describing a high-level solution; and the third as an implementation class, reused whenever possible from a library such as EiffelBase. In Eiffel, however, there is no strict distinction between these categories; it is part of the approaches seamlessness that the same notion of class, and the associated concepts, may be used at all levels of the software development process.
==Class relations==
Two relations may exist between classes:
* You can define a class <code> C </code> as a '''client''' of a class <code> A </code> to enable the features of <code> C </code> to rely on objects of type <code> A </code>.
* You may define a class <code> B </code> as an '''heir''' of a class <code> A </code> to provide <code> B </code> with all the features and properties of <code> A </code>, letting <code> B </code> add its own features and properties and modify some of the inherited features if appropriate.
* You can define a class <code>C</code> as a '''client''' of a class <code>A</code> to enable the features of <code>C</code> to rely on objects of type <code>A</code>.
* You may define a class <code>B</code> as an '''heir''' of a class <code>A</code> to provide <code>B</code> with all the features and properties of <code>A</code>, letting <code>B</code> add its own features and properties and modify some of the inherited features if appropriate.
If <code> C </code> is a client of <code> A </code>, <code> A </code> is a '''supplier''' of <code> C </code>. If <code> B </code> is an heir of <code> A </code>, <code> A </code> is a '''parent''' of <code> B </code>. A '''descendant''' of <code> A </code> is either <code> A </code> itself or, recursively, a descendant of an heir of <code> A </code>; in more informal terms a descendant is a direct or indirect heir, or the class itself. To exclude <code> A </code> itself we talk of '''proper descendant'''. In the reverse direction the terms are '''ancestor''' and '''proper ancestor'''.
If <code>C</code> is a client of <code>A</code>, <code>A</code> is a '''supplier''' of <code>C</code>. If <code>B</code> is an heir of <code>A</code>, <code>A</code> is a '''parent''' of <code>B</code>. A '''descendant''' of <code>A</code> is either <code>A</code> itself or, recursively, a descendant of an heir of <code>A</code>; in more informal terms a descendant is a direct or indirect heir, or the class itself. To exclude <code>A</code> itself we talk of '''proper descendant'''. In the reverse direction the terms are '''ancestor''' and '''proper ancestor'''.
The client relation can be cyclic; an example involving a cycle would be classes <code> PERSON </code> and <code> HOUSE </code>, modeling the corresponding informal everyday "object" types and expressing the properties that every person has a home and every home has an architect. The inheritance (heir) relation may not include any cycle.
The client relation can be cyclic; an example involving a cycle would be classes <code>PERSON</code> and <code>HOUSE</code>, modeling the corresponding informal everyday "object" types and expressing the properties that every person has a home and every home has an architect. The inheritance (heir) relation may not include any cycle.
In modeling terms, client roughly represents the relation "has" and heir roughly represents "is". For example we may use Eiffel classes to model a certain system and express that every child <code> has </code> a birth date (client relation) and is a person (inheritance).
In modeling terms, client roughly represents the relation "has" and heir roughly represents "is". For example we may use Eiffel classes to model a certain system and express that every child <code>has</code> a birth date (client relation) and is a person (inheritance).
Distinctive of Eiffel is the rule that lasses can only be connected through these two relations. This excludes the behind-the-scenes dependencies often found in other approaches, such as the use of global variables, which jeopardize the modularity of a system. Only through a strict policy of limited and explicit inter-class relations can we achieve the goals of reusability and extendibility.
==The global inheritance structure==
An Eiffel class that you write does not come into a vacuum but fits in a preordained structure, shown in the figure and involving two library classes: <code> ANY </code> and <code> NONE </code>.
An Eiffel class that you write does not come into a vacuum but fits in a preordained structure, shown in the figure and involving two library classes: <code>ANY</code> and <code>NONE</code>.
[[Image:tutorial-4]]
Any class that does not explicitly inherit from another is considered to inherit from <code> ANY </code>, so that every class is a descendant, direct or indirect, of <code> ANY </code>. <code> ANY </code> introduces a number of general-purpose features useful everywhere, such as copying, cloning and equality testing operations (page [[6 The Dynamic Structure: Execution Model|28]] ) and default input-output. The procedure <code> print </code> used in the first version of our "Hello World" (page [[4 Hello World|11]] ) comes from <code> ANY </code>.
Any class that does not explicitly inherit from another is considered to inherit from <code>ANY</code>, so that every class is a descendant, direct or indirect, of <code>ANY</code>. <code>ANY</code> introduces a number of general-purpose features useful everywhere, such as copying, cloning and equality testing operations (page [[6 The Dynamic Structure: Execution Model|28]] ) and default input-output. The procedure <code>print</code> used in the first version of our "Hello World" (page [[4 Hello World|11]] ) comes from <code>ANY</code>.
<code> NONE </code> inherits from any class that has no explicit heir. Since inheritance has no cycles, <code> NONE </code> cannot have proper descendants. This makes it useful, as we will see, to specify non-exported features, and to denote the type of void values. Unlike <code> ANY </code>, class <code> NONE </code> doesn't have an actual class text; instead, it's a convenient fiction.
<code>NONE</code> inherits from any class that has no explicit heir. Since inheritance has no cycles, <code>NONE</code> cannot have proper descendants. This makes it useful, as we will see, to specify non-exported features, and to denote the type of void values. Unlike <code>ANY</code>, class <code>NONE</code> doesn't have an actual class text; instead, it's a convenient fiction.
==Clusters==
@@ -66,7 +66,7 @@ file_status (filedesc: INTEGER): INTEGER
end
</code>
to indicate that it is actually an encapsulation of a C function whose original name is <code> fstat _ </code>. The <code> alias </code> clause is optional, but here it is needed because the C name, starting with an underscore, is not valid as an Eiffel identifier.
to indicate that it is actually an encapsulation of a C function whose original name is <code>fstat _</code>. The <code>alias</code> clause is optional, but here it is needed because the C name, starting with an underscore, is not valid as an Eiffel identifier.
Similar syntax exists to interface with C++ classes. EiffelStudio includes a tool called Legacy++ which will automatically produce, from a C++ class, an Eiffel class that encapsulates its facilities, making them available to the rest of the Eiffel software as bona fide Eiffel features.