ViewVC logotype

Contents of /trunk/Delivery/newdocs/technologies/dotnet/eiffel_dotnet_language/20_language/30_inheritance.html

Parent Directory Parent Directory | Revision Log Revision Log

Revision 34691 - (show annotations)
Thu Oct 24 19:03:19 2002 UTC (17 years, 4 months ago) by manus
File MIME type: text/html
File size: 46974 byte(s)
Fixed broken links.

1 <HTML XMLNS:MSHelp="http://msdn.microsoft.com/mshelp">
2 <HEAD>
3 <TITLE>Inheritance</TITLE>
4 <meta content="HTML 4.0" name="vs_targetSchema">
5 <LINK href="../../../../default.css" type="text/css" charset="ISO-8859-1" rel="STYLESHEET">
6 <LINK href="ms-help://Hx/HxRuntime/HxLinkDefault.css" type="text/css" rel="stylesheet">
7 <LINK href="ms-help://Hx/HxRuntime/HxLink.css" type="text/css" rel="stylesheet"></HEAD>
8 <BODY>
9 <P></LINK></LINK></LINK></P>
10 <h1>Inheritance</h1>
11 <P><MSHELP:LINK tabIndex="0" indexMoniker="!DefaultKeywordIndex" keywords="inheritance">Inheritance</MSHELP:LINK>,
12 along with
13 <MSHELP:LINK tabIndex="0" indexMoniker="!DefaultKeywordIndex" keywords="client/supplier relationship">client/supplier</MSHELP:LINK>,
14 are the two relationships that can exist between classes.
15 </P>
16 <P>Inheritance lets us mirror in software the types of abstractions that are common
17 in many problem domains, i.e., the more general to the more specialized.&nbsp;</P>
18 <P>Inheritance also gives a way&nbsp;us to combine these abstractions.
19 </P>
20 <P>Inheritance allows us to make extensions and adaptations to existing software,
21 while at the same time, leaving the original software unaltered.</P>
22 <H2>The Eiffel Inheritance Model</H2>
23 <P>If class <SPAN CLASS="eclass">B</SPAN> inherits from class <SPAN CLASS="eclass">A</SPAN>, then:
24 </P>
25 <UL>
26 <LI>
27 Every feature of <SPAN CLASS="eclass">A</SPAN> is also a feature of <SPAN CLASS="eclass">B</SPAN>
28 <LI>
29 In any case in which an
30 <MSHELP:LINK tabIndex="0" indexMoniker="!DefaultKeywordIndex" keywords="instance">instance</MSHELP:LINK>
31 of <SPAN CLASS="eclass">A</SPAN> is called for, then an instance of <SPAN CLASS="eclass">B</SPAN> will suffice.</LI></UL>
32 <P>Flexibility and adaptability are key&nbsp;qualities of the Eiffel inheritance
33 model. On an informal level, this means that, except as prevented by certain
34 constraints,&nbsp;a class can inherit from a set of classes
35 containing&nbsp;just about any&nbsp;other classes.
36 </P>
37 <P>Eiffel classes can be
38 <MSHELP:LINK tabIndex="0" indexMoniker="!DefaultKeywordIndex" keywords="effective class">effective</MSHELP:LINK>
39 or
40 <MSHELP:LINK tabIndex="0" indexMoniker="!DefaultKeywordIndex" keywords="deferred class">deferred</MSHELP:LINK>.
41 If a class is effective, then it is completely implemented.&nbsp;As a
42 result,&nbsp;it is possible to create and use
43 <MSHELP:LINK tabIndex="0" indexMoniker="!DefaultKeywordIndex" keywords="direct instance">direct
44 instances</MSHELP:LINK>
45 of an effective class at runtime.
46 </P>
47 <P>If a class is deferred, then it is not completely implemented. A class is
48 deferred if it&nbsp;contains at least one
49 <MSHELP:LINK tabIndex="0" indexMoniker="!DefaultKeywordIndex" keywords="deferred feature">deferred feature</MSHELP:LINK>.
50 So, it is possible for you&nbsp;to mark a feature (and by&nbsp;consequence also
51 its class) as deferred when you code it. This means that the specification for
52 this class dictates that such a feature exists, but there is no implementation
53 for the feature included in the class. As a result, there can be no direct
54 instances of deferred classes at runtime. However, a class that inherits from a
55 deferred class can implement, or effect, the deferred features. This results in
56 an effective descendant to the deferred class. And it is possible to create
57 direct instances of this effective descendant. Such instances would also be
58 instances (albeit not direct instances) of the original deferred class.
59 </P>
60 <P>What this means to us as software producers, is that in any development effort,
61 we have available a great number of classes which can serve as potential
62 starting points. That is, classes&nbsp;that&nbsp;we could make&nbsp;parents to
63 the classes we produce. And, those classes do not have to chosen from a strict
64 dichotomy of classes which are either completely abstract or completely
65 implemented. Inheritance from classes that are deferred&nbsp;but&nbsp;have some
66 implemented features is both&nbsp;possible and&nbsp;encouraged. It reuses
67 existing software and it reduces the opportunity for error.
68 </P>
69 <P>Consider the deferred class <SPAN CLASS="eclass">COMPARABLE</SPAN> from the Eiffel Base Library. A portion
70 of <SPAN CLASS="eclass">COMPARABLE</SPAN> is shown below:</P>
71 <CODE>
72 <SPAN CLASS="ekeyword">deferred</SPAN> <SPAN CLASS="ekeyword">class</SPAN> <br>&nbsp;&nbsp;&nbsp; <SPAN CLASS="eclass">COMPARABLE</SPAN>
73 <br>
74 <br>
75 <SPAN CLASS="ekeyword">feature</SPAN> <SPAN CLASS="ecomment">-- Comparison</SPAN>&nbsp;
76 <br>
77 <br>
78 &nbsp;&nbsp;&nbsp; <SPAN CLASS="ekeyword">infix</SPAN> "&lt;" (<SPAN CLASS="eitag">other</SPAN>: <SPAN CLASS="ekeyword">like</SPAN> <SPAN CLASS="ekeyword">Current</SPAN>): <SPAN CLASS="eclass">BOOLEAN</SPAN> <SPAN CLASS="ekeyword">is</SPAN>&nbsp;
79 <br>
80 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN CLASS="ecomment">-- Is
81 current object less than `other'?</SPAN>&nbsp;
82 <br>
83 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN CLASS="ekeyword">deferred</SPAN>&nbsp;
84 <br>
85 &nbsp;&nbsp;&nbsp; <SPAN CLASS="ekeyword">end</SPAN>&nbsp;
86 <br>
87 <br>
88 &nbsp;&nbsp;&nbsp; <SPAN CLASS="ekeyword">infix</SPAN> "&lt;=" (<SPAN CLASS="eitag">other</SPAN>: <SPAN CLASS="ekeyword">like</SPAN> <SPAN CLASS="ekeyword">Current</SPAN>): <SPAN CLASS="eclass">BOOLEAN</SPAN> <SPAN CLASS="ekeyword">is</SPAN>&nbsp;
89 <br>
90 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN CLASS="ecomment">-- Is
91 current object less than or equal to `other'?</SPAN>&nbsp;
92 <br>
93 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN CLASS="ekeyword">do</SPAN>&nbsp;
94 <br>
95 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN CLASS="ekeyword">Result</SPAN> :=
96 <SPAN CLASS="ekeyword">not</SPAN> (<SPAN CLASS="eitag">other</SPAN> &lt; <SPAN CLASS="ekeyword">Current</SPAN>)&nbsp;
97 <br>
98 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN CLASS="ekeyword">end</SPAN>&nbsp;
99 <br>
100 <br>
101 &nbsp;&nbsp;&nbsp; <SPAN CLASS="ekeyword">infix</SPAN> "&gt;" (<SPAN CLASS="eitag">other</SPAN>: <SPAN CLASS="ekeyword">like</SPAN> <SPAN CLASS="ekeyword">Current</SPAN>): <SPAN CLASS="eclass">BOOLEAN</SPAN> <SPAN CLASS="ekeyword">is</SPAN>&nbsp;
102 <br>
103 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN CLASS="ecomment">-- Is
104 current object greater than `other'?&nbsp;
105 </SPAN> <br>
106 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN CLASS="ekeyword">do</SPAN>&nbsp;
107 <br>
108 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN CLASS="ekeyword">Result</SPAN> :=
109 <SPAN CLASS="eitag">other</SPAN> &lt; <SPAN CLASS="ekeyword">Current</SPAN>&nbsp;
110 <br>
111 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN CLASS="ekeyword">end</SPAN>&nbsp;
112 <br>
113 <br>
114 &nbsp;&nbsp;&nbsp; <SPAN CLASS="ekeyword">infix</SPAN> "&gt;=" (<SPAN CLASS="eitag">other</SPAN>: <SPAN CLASS="ekeyword">like</SPAN> <SPAN CLASS="ekeyword">Current</SPAN>): <SPAN CLASS="eclass">BOOLEAN</SPAN> <SPAN CLASS="ekeyword">is</SPAN>&nbsp;
115 <br>
116 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN CLASS="ecomment">-- Is
117 current object greater than or equal to `other'?</SPAN>&nbsp;
118 <br>
119 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN CLASS="ekeyword">do</SPAN>&nbsp;
120 <br>
121 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN CLASS="ekeyword">Result</SPAN> :=
122 <SPAN CLASS="ekeyword">not</SPAN> (<SPAN CLASS="ekeyword">Current</SPAN> &lt; <SPAN CLASS="eitag">other</SPAN>)&nbsp;
123 <br>
124 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN CLASS="ekeyword">end</SPAN>&nbsp;
125 <br>
126 <br>
127 &nbsp;&nbsp;&nbsp; <SPAN CLASS="efeature">is_equal</SPAN> (<SPAN CLASS="eitag">other</SPAN>: <SPAN CLASS="ekeyword">like</SPAN> <SPAN CLASS="ekeyword">Current</SPAN>): <SPAN CLASS="eclass">BOOLEAN</SPAN> <SPAN CLASS="ekeyword">is</SPAN>&nbsp;
128 <br>
129 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN CLASS="ecomment"> -- Is
130 `other' attached to an object of the same type</SPAN>&nbsp;
131 <br>
132 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN CLASS="ecomment">-- as
133 current object and identical to it?&nbsp;
134 </SPAN> <br>
135 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN CLASS="ekeyword">do</SPAN>&nbsp;
136 <br>
137 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN CLASS="ekeyword">Result</SPAN> :=
138 (<SPAN CLASS="ekeyword">not</SPAN> (<SPAN CLASS="ekeyword">Current</SPAN> &lt; <SPAN CLASS="eitag">other</SPAN>) <SPAN CLASS="ekeyword">and</SPAN> <SPAN CLASS="ekeyword">not</SPAN> (<SPAN CLASS="eitag">other</SPAN> &lt; <SPAN CLASS="ekeyword">Current</SPAN>))&nbsp;
139 <br>
140 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN CLASS="ekeyword">end</SPAN>
141 </CODE>
142 <P>If you are producing a class that you wish to support basic comparison
143 operators, like&nbsp;"&lt;" and&nbsp;"&gt;", you can have that class inherit
144 from <SPAN CLASS="eclass">COMPARABLE</SPAN>, which has features which correspond to those operators. The
145 text for <SPAN CLASS="eclass">COMPARABLE</SPAN> contains eight features. Seven of these are effective and
146 one is deferred.
147 </P>
148 <P>So through inheritance from <SPAN CLASS="eclass">COMPARABLE</SPAN>, your class, let's call it <SPAN CLASS="eclass">WHATZIT</SPAN>, would
149 now have these features available. But how would the features of <SPAN CLASS="eclass">COMPARABLE</SPAN>
150 know&nbsp;what it means&nbsp;to compare <SPAN CLASS="eclass">WHATZIT</SPAN>s?
151 </P>
152 <P>Of course, it would have no way of knowing, so you must show it. And you do that
153 by writing the implementation for "&lt;", the one deferred feature that <SPAN CLASS="eclass">WHATZIT</SPAN>
154 inherits from the <SPAN CLASS="eclass">COMPARABLE</SPAN> class.
155 </P>
156 <P>When you look closely at the effective features of <SPAN CLASS="eclass">COMPARABLE</SPAN>, you see that
157 their implementations are ultimately based on "&lt;". If we were not able to
158 inherit from multiple partially implemented classes, then we would be forced to
159 implement many more features, a process which invites error, or, in the case of
160 comparison,&nbsp;to move to a less appealing model.
161 </P>
162 <H2>The Inheritance Part of Classes in Eiffel</H2>
163 <P>Because the inheritance model has such flexibility, it must also have
164 adaptability. A consequence of inheriting from multiple classes is that&nbsp;it
165 would be possible to&nbsp;inherit multiple features with the same name ... and
166 you remember from&nbsp;<A href="../../eiffel_for_dotnet/20_language/20_adding_class_features.html">Adding
167 Class Features</A>&nbsp;that a class is not allowed to have more than one
168 feature with the same name. A process called feature adaptation allows us to
169 resolve these issues in an heir. Feature adaptation is also done for reasons
170 other than resolving name clashes as well.</P>
171 <P>Feature adaptation is an enabling capability, but it is also one that takes some
172 study to understand fully.
173 </P>
174 <P>We will look at the types of feature adaptation that will serve most useful to
175 you as you begin to produce Eiffel software.</P>
176 <P>In&nbsp;<A href="../../eiffel_for_dotnet/20_language/10_eiffel_classes.html">Eiffel Classes</A>
177 you saw where the inheritance part fits into the class structure. Shown below
178 is a portion of class&nbsp;<SPAN CLASS="eclass">LINKED_QUEUE</SPAN>&nbsp;from the Eiffel libraries.
179 <SPAN CLASS="eclass">LINKED_QUEUE</SPAN> is an effective class which implements the abstract notion of a
180 <SPAN CLASS="eclass">QUEUE</SPAN> (a deferred class)&nbsp;with an implementation based on the services
181 provided by <SPAN CLASS="eclass">LINKED_LIST</SPAN> (an effective class).</P>
182 <CODE><SPAN CLASS="ekeyword">class</SPAN> <BR>&nbsp;&nbsp;&nbsp; <SPAN CLASS="eclass">LINKED_QUEUE</SPAN> [<SPAN CLASS="egeneric">G</SPAN>]
183 <br>
184 <SPAN CLASS="ekeyword">inherit</SPAN>&nbsp;
185 <BR>
186 &nbsp;&nbsp;&nbsp;&nbsp; <SPAN CLASS="eclass">QUEUE</SPAN> [<SPAN CLASS="egeneric">G</SPAN>]&nbsp;&nbsp;
187 <br>
188 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
189 <SPAN CLASS="ekeyword">undefine</SPAN>&nbsp;&nbsp;
190 <br>
191 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
192 <SPAN CLASS="efeature">is_empty</SPAN>,&nbsp;&nbsp;
193 <br>
194 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
195 <SPAN CLASS="efeature">copy</SPAN>,&nbsp;&nbsp;
196 <br>
197 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
198 <SPAN CLASS="efeature">is_equal</SPAN>&nbsp;&nbsp;
199 <br>
200 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
201 <SPAN CLASS="efeature">redefine</SPAN>&nbsp;&nbsp;
202 <br>
203 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
204 <SPAN CLASS="efeature">linear_representation</SPAN>,&nbsp;&nbsp;
205 <br>
206 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
207 <SPAN CLASS="efeature">prune_all</SPAN>,&nbsp;&nbsp;
208 <br>
209 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
210 <SPAN CLASS="efeature">extend</SPAN>&nbsp;&nbsp;
211 <br>
212 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
213 <SPAN CLASS="ekeyword">select</SPAN>&nbsp;&nbsp;
214 <br>
215 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
216 <SPAN CLASS="efeature">item</SPAN>,&nbsp;&nbsp;
217 <br>
218 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
219 <SPAN CLASS="efeature">put</SPAN>&nbsp;&nbsp;
220 <br>
221 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN CLASS="ekeyword">end</SPAN>&nbsp;
222 <br>
223 &nbsp;&nbsp;&nbsp; <SPAN CLASS="eclass">LINKED_LIST</SPAN> [<SPAN CLASS="egeneric">G</SPAN>]&nbsp;
224 <br>
225 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN CLASS="ekeyword">rename</SPAN>&nbsp;
226 <br>
227 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
228 <SPAN CLASS="efeature">item</SPAN> <SPAN CLASS="ekeyword">as</SPAN> <SPAN CLASS="efeature">ll_item</SPAN>,&nbsp;
229 <br>
230 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
231 <SPAN CLASS="efeature">remove</SPAN> <SPAN CLASS="ekeyword">as</SPAN> <SPAN CLASS="efeature">ll_remove</SPAN>,&nbsp;
232 <br>
233 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
234 <SPAN CLASS="efeature">make</SPAN> <SPAN CLASS="ekeyword">as</SPAN> <SPAN CLASS="efeature">ll_make</SPAN>,&nbsp;
235 <br>
236 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
237 <SPAN CLASS="efeature">remove_left</SPAN> <SPAN CLASS="ekeyword">as</SPAN> <SPAN CLASS="efeature">remove</SPAN>,&nbsp;
238 <br>
239 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
240 <SPAN CLASS="efeature">put</SPAN> <SPAN CLASS="ekeyword">as</SPAN> <SPAN CLASS="efeature">ll_put</SPAN>&nbsp;
241 <br>
242 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN CLASS="ekeyword">export</SPAN>&nbsp;
243 <br>
244 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
245 {<SPAN CLASS="eclass">NONE</SPAN>}&nbsp;
246 <br>
247 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
248 <SPAN CLASS="ekeyword">all</SPAN>&nbsp;
249 <br>
250 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
251 {<SPAN CLASS="eclass">ANY</SPAN>}&nbsp;
252 <br>
253 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
254 <SPAN CLASS="efeature">writable</SPAN>,&nbsp;
255 <br>
256 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
257 <SPAN CLASS="efeature">extendible</SPAN>,&nbsp;
258 <br>
259 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
260 <SPAN CLASS="efeature">wipe_out</SPAN>,&nbsp;
261 <br>
262 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
263 <SPAN CLASS="efeature">readable</SPAN>&nbsp;
264 <br>
265 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
266 <SPAN CLASS="ekeyword">undefine</SPAN>&nbsp;
267 <br>
268 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
269 <SPAN CLASS="efeature">fill</SPAN>,&nbsp;
270 <br>
271 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
272 <SPAN CLASS="efeature">append</SPAN>,&nbsp;
273 <br>
274 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
275 <SPAN CLASS="efeature">prune</SPAN>,&nbsp;
276 <br>
277 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
278 <SPAN CLASS="efeature">readable</SPAN>,&nbsp;
279 <br>
280 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
281 <SPAN CLASS="efeature">writable</SPAN>,&nbsp;
282 <br>
283 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
284 <SPAN CLASS="efeature">prune_all</SPAN>,&nbsp;
285 <br>
286 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
287 <SPAN CLASS="efeature">extend</SPAN>,&nbsp;
288 <br>
289 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
290 <SPAN CLASS="efeature">force</SPAN>,&nbsp;
291 <br>
292 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
293 <SPAN CLASS="efeature">is_inserted</SPAN>&nbsp;
294 <br>
295 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
296 <SPAN CLASS="ekeyword">redefine</SPAN>&nbsp;
297 <br>
298 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
299 <SPAN CLASS="efeature">duplicate</SPAN>,&nbsp;
300 <br>
301 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
302 <SPAN CLASS="efeature">linear_representation</SPAN>&nbsp;
303 <br>
304 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN CLASS="ekeyword">select</SPAN>&nbsp;
305 <br>
306 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
307 <SPAN CLASS="efeature">remove</SPAN>&nbsp;
308 <br>
309 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN CLASS="ekeyword">end</SPAN>
310 </CODE>
311 <P>Okay ... now calm down ... please. This is an example from a very highly-evolved
312 and sophisticated library which is replete with software reuse. <SPAN CLASS="eclass">LINKED_QUEUE</SPAN>
313 has two parents and uses considerable feature adaptation.&nbsp;In fact, it uses
314 every feature adaptation&nbsp;option available. The benefit is obvious,
315 though.&nbsp;<SPAN CLASS="eclass">LINKED_QUEUE</SPAN> class&nbsp;has only seven
316 features&nbsp;actually&nbsp;coded.&nbsp;In&nbsp;total there
317 are&nbsp;only&nbsp;26 lines of instructions!</P>
318 <P>In practice you can use inheritance, even multiple inheritance, to do some quite
319 productive programming in Eiffel without having to write anything that looks
320 like the inheritance part of <SPAN CLASS="eclass">LINKED_QUEUE</SPAN> above.</P>
321 <P>Regardless, let's&nbsp;break&nbsp;<SPAN CLASS="eclass">LINKED_QUEUE</SPAN>'s inheritance part&nbsp;into
322 chunks&nbsp;and take a look at some of them.</P>
323 <h3>Rename</h3>
324 <CODE>
325 <P><FONT color="darkgray">class <BR>&nbsp;&nbsp;&nbsp; LINKED_QUEUE [G]
326 <BR>
327 inherit&nbsp;<BR>
328 &nbsp;&nbsp;&nbsp;&nbsp;LINKED_LIST [G]&nbsp; </FONT>
329 </P>
330 <P><BR>
331 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN CLASS="ekeyword">rename</SPAN>&nbsp;
332 <BR>
333 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
334 <SPAN CLASS="efeature">item</SPAN> <SPAN CLASS="ekeyword">as</SPAN> <SPAN CLASS="efeature">ll_item</SPAN>,&nbsp;
335 <BR>
336 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
337 <SPAN CLASS="efeature">remove</SPAN> <SPAN CLASS="ekeyword">as</SPAN> <SPAN CLASS="efeature">ll_remove</SPAN>,&nbsp;
338 <BR>
339 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
340 <SPAN CLASS="efeature">make</SPAN> <SPAN CLASS="ekeyword">as</SPAN> <SPAN CLASS="efeature">ll_make</SPAN>,&nbsp;
341 <BR>
342 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
343 <SPAN CLASS="efeature">remove_left</SPAN> <SPAN CLASS="ekeyword">as</SPAN> <SPAN CLASS="efeature">remove</SPAN>,&nbsp;
344 <BR>
345 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
346 <SPAN CLASS="efeature">put</SPAN> <SPAN CLASS="ekeyword">as</SPAN> <SPAN CLASS="efeature">ll_put</SPAN>&nbsp;&nbsp;<BR>
347 &nbsp;&nbsp;&nbsp;</P>
348 </CODE>
349 <P>As you might have already guessed, the rename part, introduced oddly enough by
350 the keyword "<SPAN CLASS="ekeyword">rename</SPAN>", is used to rename features.</P>
351 <P>Specifically, it is used when an heir wants to use a feature from a parent, but
352 wants to use it under a different name than that by which the parent knows it.
353 So in the example, the feature known as <SPAN CLASS="efeature">item</SPAN> in <SPAN CLASS="eclass">LINKED_LIST</SPAN> is perfectly
354 usable in <SPAN CLASS="eclass">LINKED_QUEUE</SPAN>, but must be applied as <SPAN CLASS="efeature">ll_item</SPAN>.
355 </P>
356 <P>This is common when your&nbsp;class&nbsp;inherits two different features with
357 the same name from two different parents and you want to be able to use them
358 both. Because you can only have one feature with a given name, then rename one
359 of the features.</P>
360 <h3>New Exports</h3>
361 <CODE>
362 <P><FONT color="darkgray">class <BR>&nbsp;&nbsp;&nbsp; LINKED_QUEUE [G]
363 <BR>
364 inherit&nbsp;<BR>
365 &nbsp;&nbsp;&nbsp;&nbsp;LINKED_LIST [G]&nbsp; </FONT>
366 </P>
367 <P><BR>
368 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN CLASS="ekeyword">export</SPAN>&nbsp;
369 <BR>
370 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
371 {<SPAN CLASS="eclass">NONE</SPAN>}&nbsp;
372 <BR>
373 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
374 <SPAN CLASS="ekeyword">all</SPAN>&nbsp;
375 <BR>
376 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
377 {<SPAN CLASS="eclass">ANY</SPAN>}&nbsp;
378 <BR>
379 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
380 <SPAN CLASS="efeature">writable</SPAN>,&nbsp;
381 <BR>
382 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
383 <SPAN CLASS="efeature">extendible</SPAN>,&nbsp;
384 <BR>
385 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
386 <SPAN CLASS="efeature">wipe_out</SPAN>,&nbsp;
387 <BR>
388 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
389 <SPAN CLASS="efeature">readable</SPAN>&nbsp;&nbsp;<BR>
390 &nbsp;&nbsp;</P>
391 </CODE>
392 <P>The new exports part is introduced by the keyword "<SPAN CLASS="ekeyword">export</SPAN>". This section allows
393 you to change the export status of inherited features. Remember from&nbsp;<A href="../../eiffel_for_dotnet/20_language/20_adding_class_features.html">Adding
394 Class Features</A> that features become available (or not) to clients by
395 their export status. Export status of immediate features is controlled in the
396 feature clause. But here we are dealing with inherited features, so we control
397 their status in the export part of the class's inheritance section. Any feature
398 not mentioned will have the same export status as it did in the parent class.
399 </P>
400 <P>In this example, the keyword "<SPAN CLASS="ekeyword">all</SPAN>" is used first to say that all features
401 inherited form <SPAN CLASS="eclass">LINKED_LIST</SPAN> are unavailable to any clients (export to class
402 <SPAN CLASS="eclass">NONE</SPAN>). This is typical for&nbsp;a class like <SPAN CLASS="eclass">LINKED_QUEUE</SPAN>&nbsp;in which the
403 features important to the client come from the deferred parent, in this case
404 <SPAN CLASS="eclass">QUEUE</SPAN>, and the class <SPAN CLASS="eclass">LINKED_LIST</SPAN> is used only for implementation. But, it seems
405 that also in this case, the producer&nbsp;felt differently&nbsp;about the
406 features <SPAN CLASS="efeature">writable</SPAN>, <SPAN CLASS="efeature">extendible</SPAN>, <SPAN CLASS="efeature">wipe_out</SPAN>, and <SPAN CLASS="efeature">readable</SPAN>, and decided the
407 allow clients of <SPAN CLASS="eclass">ANY</SPAN> type to utilize these features inherited from <SPAN CLASS="eclass">LINKED_LIST</SPAN>.
408 </P>
409 <h3>Undefine</h3>
410 <CODE>
411 <P><FONT color="darkgray">class <BR>&nbsp;&nbsp;&nbsp; LINKED_QUEUE [G]
412 <BR>
413 inherit&nbsp;<BR>
414 &nbsp;&nbsp;&nbsp;&nbsp;LINKED_LIST [G]&nbsp; </FONT>
415 </P>
416 <P><BR>
417 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
418 <SPAN CLASS="ekeyword">undefine</SPAN>&nbsp;&nbsp;
419 <BR>
420 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
421 <SPAN CLASS="efeature">is_empty</SPAN>,&nbsp;&nbsp;
422 <BR>
423 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
424 <SPAN CLASS="efeature">copy</SPAN>,&nbsp;&nbsp;
425 <BR>
426 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
427 <SPAN CLASS="efeature">is_equal</SPAN>&nbsp;&nbsp;&nbsp;<BR>
428 &nbsp;&nbsp;</P>
429 </CODE>
430 <P>Next, undefine ... it's probably not what you think. You might assume that
431 undefine is a way to banish forever any inherited features that you just do not
432 want to deal with. But what happens to features whose names are listed&nbsp;in
433 an undefine clause is that they become deferred features in the heir.
434 </P>
435 <P>Undefine is useful if you inherit two different features of the same name from
436 different parents, a situation you cannot live with. If you like one and you
437 don't like the other, then you can undefine the one you don't like. The the
438 only version you get is the one you like.
439 </P>
440 <P>Another&nbsp;way you might use undefine is&nbsp;in the case in which
441 you&nbsp;actually want&nbsp;a feature to be deferred in an heir that was
442 effective in a parent.</P>
443 <h3>Redefine</h3>
444 <CODE>
445 <P><FONT color="darkgray">class <BR>&nbsp;&nbsp;&nbsp; LINKED_QUEUE [G]
446 <BR>
447 inherit&nbsp;<BR>
448 &nbsp;&nbsp;&nbsp;&nbsp;LINKED_LIST [G]</FONT>
449 </P>
450 <BR>
451 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
452 <SPAN CLASS="ekeyword">redefine</SPAN>&nbsp;&nbsp;
453 <BR>
454 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
455 <SPAN CLASS="efeature">linear_representation</SPAN>,&nbsp;&nbsp;
456 <BR>
457 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
458 <SPAN CLASS="efeature">prune_all</SPAN>,&nbsp;&nbsp;
459 <BR>
460 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
461 <SPAN CLASS="efeature">extend</SPAN>&nbsp;&nbsp;&nbsp;<BR>
462 &nbsp;&nbsp;</P>
463 </CODE>
464 <P>The redefine part lists the names of effective features for which the producer
465 of the heir class would like to provide implementations that replace the
466 inherited implementations.
467 </P>
468 <P>So,&nbsp;in this example&nbsp;the implementation for <SPAN CLASS="efeature">linear_representation</SPAN>,
469 for example, that <SPAN CLASS="eclass">LINKED_QUEUE</SPAN> would have inherited from <SPAN CLASS="eclass">QUEUE</SPAN> will not be
470 used. Instead <SPAN CLASS="eclass">LINKED_QUEUE</SPAN> implements its own version of
471 <SPAN CLASS="efeature">linear_representation</SPAN>.
472 </P>
473 <DIV class="note" id="DIV1" style="WIDTH: 80%">
474 <P><STRONG>Note:</STRONG> When a class implements a version of an inherited feature
475 which was deferred in its parent, this is known as "effecting" the feature.
476 Because features being effected&nbsp;are getting their first implementation, it
477 is not necessary to list their names in the redefine part, or anywhere
478 else&nbsp;in the inheritance part of the heir.</P>
480 </DIV>
481 <h3>Select</h3>
482 <CODE>
483 <P><FONT color="darkgray">class <BR>&nbsp;&nbsp;&nbsp; LINKED_QUEUE [G]
484 <BR>
485 inherit&nbsp;<BR>
486 &nbsp;&nbsp;&nbsp;&nbsp;LINKED_LIST [G]</FONT>
487 </P>
488 <BR>
489 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
490 <SPAN CLASS="ekeyword">select</SPAN>&nbsp;
491 <BR>
492 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
493 <SPAN CLASS="efeature">remove</SPAN>&nbsp;
494 <BR>
495 </P>
496 </CODE>
497 <P>The select part is used only under special circumstances. The case in which
498 select&nbsp;is required&nbsp;involves a situation called "repeated"
499 inheritance. Repeated inheritance occurs when an heir inherits more than once
500 from the same ancestor. Usually this means it has two or more parents who have
501 a common proper ancestor (but it can occur directly). The features from the
502 common ancestor are inherited by each of the parents and passed on to the heir.
503 The rules and effects of repeated inheritance occupy an entire chapter in the
504 official Eiffel language reference and will not be reproduced here.&nbsp;Just
505 understand at this point&nbsp;that it is sometimes necessary to use <SPAN CLASS="ekeyword">select</SPAN>
506 to&nbsp;provide the dynamic binding system&nbsp;with an unambiguous choice of
507 features in the presence of polymorphic attachment.</P>
508 <P>You should note&nbsp;also that repeated inheritance can and does occur often without
509 causing any&nbsp;problem at all. In fact it happens in every case of multiple
510 inheritance, due to the fact that all classes inherit from class ANY and
511 receive its features as a result. The reason it is not a problem is that in the
512 case that any feature makes it from the original common ancestor along multiple
513 paths to the&nbsp;heir&nbsp;with its name and implementation still intact,
514 it&nbsp;will arrive as only one feature heir. This is called sharing and
515 nothing special needs to be done to make it happen.</P>
516 <H2>Polymorphism</H2>
517 <P>It is time now to see another way in which inheritance helps build more
518 extendible software.
519 </P>
520 <P>Assume that we have to build classes that model different&nbsp;types of
521 polygons. We would do this by building a class for polygon which would model a
522 garden-variety polygon, a multi-sided closed figure. But when we consider that
523 there are specialized types of polygons, like triangles and rectangles, we
524 realize that to support these specializations, we need classes for them as
525 well. And this is an obvious opportunity for inheritance. All triangles and
526 rectangles <EM>are</EM> polygons. So, we start with class <SPAN CLASS="eclass">POLYGON</SPAN> and its
527 proper descendants <SPAN CLASS="eclass">TRIANGLE</SPAN> and <SPAN CLASS="eclass">RECTANGLE</SPAN>.</P>
528 <P>So we can make declarations like:</P>
529 <CODE>
530 <P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN CLASS="efeature">my_polygon</SPAN>: <SPAN CLASS="eclass">POLYGON</SPAN><BR>
531 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<SPAN CLASS="efeature">your_polygon</SPAN>: <SPAN CLASS="eclass">POLYGON</SPAN><BR>
532 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN CLASS="efeature">my_triangle</SPAN>: <SPAN CLASS="eclass">TRIANGLE</SPAN>&nbsp;<BR>
533 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN CLASS="efeature">my_rectangle</SPAN>: <SPAN CLASS="eclass">RECTANGLE</SPAN>&nbsp;&nbsp;<BR>
534 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN CLASS="efeature">another_rectangle</SPAN>: <SPAN CLASS="eclass">RECTANGLE</SPAN></P>
535 </CODE>
536 <P>Assume these declarations are in force for all the examples this section on
537 polymorphism.</P>
538 <P>We saw in&nbsp;<A href="../../eiffel_for_dotnet/20_language/20_adding_class_features.html">Adding
539 Class Features</A> that we can say that one class conforms to another if it
540 is the same class or one of its proper descendants. Therefore POLYGON conforms
541 to <SPAN CLASS="eclass">POLYGON</SPAN>. Also, <SPAN CLASS="eclass">TRIANGLE</SPAN> and <SPAN CLASS="eclass">RECTANGLE</SPAN> conform to <SPAN CLASS="eclass">POLYGON</SPAN>. But,
542 importantly,&nbsp;<SPAN CLASS="eclass">POLYGON</SPAN> <EM>does not</EM> conform to <SPAN CLASS="eclass">TRIANGLE</SPAN> or <SPAN CLASS="eclass">RECTANGLE</SPAN>.
543 This makes sense intuitively, because we know all rectangles and triangles are
544 polygons ... and we also know that not all polygons are rectangles.
545 </P>
546 <h3>Polymorphic Attachment</h3>
547 <P>These facts affect how assignments can work. Using the declarations above:</P>
548 <CODE>
549 <P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN CLASS="efeature">my_polygon</SPAN> :=
550 <SPAN CLASS="efeature">your_polygon</SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
551 <SPAN CLASS="ecomment">-- Is valid</SPAN><BR>
552 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN CLASS="efeature">your_polygon</SPAN> :=
553 <SPAN CLASS="efeature">my_polygon</SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
554 <SPAN CLASS="ecomment"> -- Is valid</SPAN> <BR>
555 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN CLASS="efeature">my_polygon</SPAN> :=
556 <SPAN CLASS="efeature">my_rectangle</SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN CLASS="ecomment">--
557 Is valid<BR>
558 </SPAN> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN CLASS="efeature">my_polygon</SPAN> :=
559 <SPAN CLASS="efeature">my_triangle</SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
560 <SPAN CLASS="ecomment">-- Is valid</SPAN></P>
561 </CODE>
562 <P>but</P>
563 <CODE>
564 <P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN CLASS="efeature">my_rectangle</SPAN> :=
565 <SPAN CLASS="efeature">my_polygon</SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
566 <SPAN CLASS="ecomment">-- Is not valid</SPAN><BR>
567 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN CLASS="efeature">my_triangle</SPAN> :=
568 <SPAN CLASS="efeature">my_polygon</SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
569 <SPAN CLASS="ecomment">-- Is not valid</SPAN></P>
570 </CODE>
571 <P>and of course</P>
572 <CODE>
573 <P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN CLASS="efeature">my_rectangle</SPAN> :=
574 <SPAN CLASS="efeature">my_triangle</SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
575 <SPAN CLASS="ecomment">-- Is not valid</SPAN></P>
576 </CODE>
577 <P>Consider now the assignment below&nbsp;which&nbsp;is valid.</P>
578 <CODE>
579 <P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN CLASS="efeature">my_polygon</SPAN> :=
580 <SPAN CLASS="efeature">my_rectangle</SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</P>
581 </CODE>
582 <P>After an assignment&nbsp;like this executes the entity <SPAN CLASS="efeature">my_polygon</SPAN> will be
583 holding at runtime a reference to an instance of a type which is not a direct
584 instance of its declared type <SPAN CLASS="eclass">POLYGON</SPAN>. But conformance ensures us that,
585 although it may not be a direct instance, it will indeed by an instance. (all
586 rectangles are polygons).</P>
587 <P>Depending upon how many different types of polygons get modeled in classes, the
588 entity "<SPAN CLASS="efeature">my_polygon</SPAN>" could be attached objects of may different types ... it
589 could take on many forms. This in fact is the basis for the term
590 "polymorphism"; having many forms. So we speak of "polymorphic attachment" as
591 the process by which at runtime entities can hold references to objects which
592 are not of the entity's declared type ... but they are of conforming types.</P>
593 <P>Now let's see how we get some value from this.</P>
594 <h3>Dynamic Binding</h3>
595 <P>Suppose that one of the features of <SPAN CLASS="eclass">POLYGON</SPAN> is a
596 query&nbsp;<SPAN CLASS="efeature">perimeter</SPAN>&nbsp;which returns&nbsp;an instance's&nbsp;perimeter.
597 The producer of <SPAN CLASS="eclass">POLYGON</SPAN> may have implemented <SPAN CLASS="efeature">perimeter</SPAN> as a function that
598 computes the perimeter by adding up the lengths of all the sides. This approach
599 is guaranteed to work for all polygons, and we can apply the <SPAN CLASS="efeature">perimeter</SPAN> feature
600 to any polygon. Let's print some perimeters:</P>
601 <CODE>
602 <P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN CLASS="efeature">print</SPAN> (<SPAN CLASS="efeature">my_polygon</SPAN>.<SPAN CLASS="efeature">perimeter</SPAN>)<BR>
603 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN CLASS="efeature">print</SPAN>
604 (<SPAN CLASS="efeature">my_triangle</SPAN>.<SPAN CLASS="efeature">perimeter</SPAN>)&nbsp;<BR>
605 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN CLASS="efeature">print</SPAN> (<SPAN CLASS="efeature">my_rectangle</SPAN>.<SPAN CLASS="efeature">perimeter</SPAN>)</P>
606 </CODE>
607 <P><SPAN CLASS="eclass">TRIANGLE</SPAN> and <SPAN CLASS="eclass">RECTANGLE</SPAN> might have properties, expressed as queries, which as a
608 part of their specialization, distinguish them from run-of-the-mill polygons.
609 Two features of rectangles are <SPAN CLASS="efeature">width</SPAN> and <SPAN CLASS="efeature">height</SPAN> the lengths of the sides.
610 </P>
611 <P>Armed with these <SPAN CLASS="eclass">RECTANGLE</SPAN>-specific features, the producer of <SPAN CLASS="eclass">RECTANGLE</SPAN> may say,
612 "Now I no longer have to depend upon that crude implementation of <SPAN CLASS="efeature">perimeter</SPAN>
613 that is inherited from <SPAN CLASS="eclass">POLYGON</SPAN>. I can build an efficient <SPAN CLASS="eclass">RECTANGLE</SPAN>-specific
614 implementation of <SPAN CLASS="efeature">perimeter</SPAN>, based on the knowledge that for all <SPAN CLASS="eclass">RECTANGLE</SPAN>s
615 perimeter = 2*(width+height)"</P>
616 <P>To implement this specialized version of <SPAN CLASS="eclass">perimeter</SPAN>, the producer of <SPAN CLASS="eclass">RECTANGLE</SPAN>
617 must add the feature to the class, but also must list its name in the
618 "<SPAN CLASS="ekeyword">redefine</SPAN>" part of the <SPAN CLASS="eclass">RECTANGLE</SPAN>'s inheritance clause.</P>
619 <CODE>
620 <P><SPAN CLASS="ekeyword">class</SPAN> <SPAN CLASS="eclass">RECTANGLE</SPAN><BR>
621 <SPAN CLASS="ekeyword">inherit</SPAN><BR>
622 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN CLASS="eclass">POLYGON</SPAN><BR>
623 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN CLASS="ekeyword">redefine</SPAN><BR>
624 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
625 <SPAN CLASS="efeature">perimeter</SPAN>&nbsp;<BR>
626 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN CLASS="ekeyword">end</SPAN><BR>
627 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.&nbsp;&nbsp;<BR>
628 &nbsp;&nbsp;&nbsp;&nbsp; .<BR>
629 <SPAN CLASS="ekeyword">feature</SPAN><BR>
630 &nbsp;&nbsp;&nbsp;&nbsp;<SPAN CLASS="ekeyword">perimeter</SPAN>: <SPAN CLASS="eclass">REAL</SPAN> <SPAN CLASS="ekeyword">is</SPAN><BR>
631 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN CLASS="ecomment"> --&nbsp;Sum
632 of lengths of all sides<BR>
633 </SPAN> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN CLASS="ekeyword">do</SPAN><BR>
634 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN CLASS="ekeyword">Result</SPAN>
635 := 2 * (<SPAN CLASS="efeature">width</SPAN> +&nbsp;<SPAN CLASS="efeature">height</SPAN>)<BR>
636 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN CLASS="ekeyword">end</SPAN><BR>
637 </P>
638 </CODE>
639 <P>You would expect then, that this version of <SPAN CLASS="efeature">perimeter</SPAN> would be executed in the
640 following context:</P>
641 <CODE>
642 <P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN CLASS="efeature">print</SPAN> (<SPAN CLASS="efeature">my_rectangle</SPAN>.<SPAN CLASS="efeature">perimeter</SPAN>)</P>
643 </CODE>
644 <P>But what makes this interesting is that even in the context below</P>
645 <CODE>
646 <P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN CLASS="efeature">my_polygon</SPAN> := <SPAN CLASS="efeature">my_rectangle</SPAN>&nbsp;<BR>
648 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN CLASS="efeature">print</SPAN> (<SPAN CLASS="efeature">my_polygon</SPAN>.<SPAN CLASS="efeature">perimeter</SPAN>)</P>
649 </CODE>
650 <P>in which <SPAN CLASS="efeature">perimeter</SPAN> is being applied to a entity declared as <SPAN CLASS="eclass">POLYGON</SPAN>, the
651 specialized version of <SPAN CLASS="efeature">perimeter</SPAN> from <SPAN CLASS="eclass">RECTANGLE</SPAN> is being used. It would be
652 impossible to ensure at compile time which version of <SPAN CLASS="efeature">perimeter</SPAN> is most
653 appropriate. So it must be done at runtime. This ability to choose the best
654 version of a feature to apply, just&nbsp;at the moment&nbsp;it needs to be
655 applied, is called "dynamic binding".</P>
656 <P>Static typing tells us at compile time that it is safe to apply <SPAN CLASS="efeature">perimeter</SPAN> to
657 <SPAN CLASS="efeature">my_polygon</SPAN> No matter which of the&nbsp;types of polygons is attached to
658 <SPAN CLASS="efeature">my_polygon</SPAN>, there will be a <SPAN CLASS="efeature">perimeter</SPAN> feature that will work.
659 </P>
660 <P>Dynamic binding tells us that when we&nbsp;apply <SPAN CLASS="efeature">perimeter</SPAN>, we know that the
661 most appropriate version of the feature will get applied at runtime.
662 </P>
663 <h3>Assignment Attempt</h3>
664 <P>Now let's add another situation. Consider the code below:</P>
665 <CODE>
666 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN CLASS="efeature">my_polygon</SPAN> := <SPAN CLASS="efeature">my_rectangle</SPAN>&nbsp;<br>
667 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN CLASS="efeature">print</SPAN> (<SPAN CLASS="efeature">my_polygon</SPAN>.<SPAN CLASS="efeature">perimeter</SPAN>)<br>
668 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN CLASS="efeature">print</SPAN>
669 (<SPAN CLASS="efeature">my_polygon</SPAN>.<SPAN CLASS="efeature">width</SPAN>)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
670 <SPAN CLASS="ecomment">-- Is invalid</SPAN><br>
671 </CODE>
672 <P>We could apply <SPAN CLASS="efeature">perimeter</SPAN> to <SPAN CLASS="efeature">my_polygon</SPAN> and everything is fine ... we
673 even get <SPAN CLASS="eclass">RECTANGLE</SPAN>'s specialized version of the feature. But it is invalid for
674 us to try to apply <SPAN CLASS="efeature">width</SPAN> to <SPAN CLASS="efeature">my_polygon</SPAN> even though we feel (with rather
675 strong conviction) that at this point in execution, <SPAN CLASS="efeature">my_polygon</SPAN> will be
676 attached to an object of type <SPAN CLASS="eclass">RECTANGLE</SPAN>, and we know that <SPAN CLASS="efeature">width</SPAN> is a valid
677 query on <SPAN CLASS="eclass">RECTANGLE</SPAN>s.</P>
678 <P>The reason follows. When we declared <SPAN CLASS="efeature">my_polygon</SPAN> as type <SPAN CLASS="eclass">POLYGON</SPAN>, we made a
679 deal that says that the only features that can be applied to <SPAN CLASS="efeature">my_polygon</SPAN> are
680 the features of <SPAN CLASS="eclass">POLYGON</SPAN>. Remember that static typing guarantees us at compile
681 time&nbsp;that at runtime there&nbsp;will be&nbsp;at least one version of the
682 feature available that can be applied.
683 </P>
684 <CODE>
685 <P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN CLASS="efeature">print</SPAN>
686 (<SPAN CLASS="efeature">my_polygon</SPAN>.<SPAN CLASS="efeature">width</SPAN>)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
687 <SPAN CLASS="ecomment">-- Is invalid</SPAN></P>
688 </CODE>
689 <P>But in the case above, the guarantee cannot be made. <SPAN CLASS="efeature">my_polygon</SPAN> is declared
690 with class <SPAN CLASS="eclass">POLYGON</SPAN> which has no <SPAN CLASS="efeature">width</SPAN> feature, despite the fact that some of
691 its proper descendants might.</P>
692 <P>Does this mean that we can never do <SPAN CLASS="eclass">RECTANGLE</SPAN> things with this instance again,
693 once we have attached it to <SPAN CLASS="efeature">my_polygon</SPAN>?</P>
694 <P>No. There is a language facility called the "assignment attempt" which will come
695 to our rescue. The assignment attempt will allow us safely to attach our
696 instance back to an entity typed as <SPAN CLASS="eclass">RECTANGLE</SPAN>. After doing so, we are free use
697 <SPAN CLASS="eclass">RECTANGLE</SPAN> features.
698 </P>
700 <CODE>
701 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN CLASS="efeature">my_polygon</SPAN> := <SPAN CLASS="efeature">my_rectangle</SPAN><BR>
702 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN CLASS="efeature">print</SPAN> (<SPAN CLASS="efeature">my_polygon</SPAN>.<SPAN CLASS="efeature">perimeter</SPAN>)<BR>
703 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN CLASS="efeature">another_rectangle</SPAN> ?= <SPAN CLASS="efeature">my_polygon</SPAN><BR>
704 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN CLASS="efeature">print</SPAN> (<SPAN CLASS="efeature">another_rectangle</SPAN>.<SPAN CLASS="efeature">width</SPAN>)<BR>
705 </CODE>
706 <P>The assignment attempt uses the syntax "?=", versus the ":=" of assignment.</P>
707 <P>This is significant ... as is the name assignment <EM>attempt</EM>. The reason
708 is that it is possible in some context that <SPAN CLASS="efeature">my_polygon</SPAN> will be attached to
709 something other than a rectangle when we do this:</P>
710 <CODE>
711 <P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN CLASS="efeature">another_rectangle</SPAN> ?= <SPAN CLASS="efeature">my_polygon</SPAN></P>
712 </CODE>
713 <P>If it were true that <SPAN CLASS="efeature">my_polygon</SPAN> were attached to an instance of say <SPAN CLASS="eclass">TRIANGLE</SPAN>
714 when the assignment attempt above was executed, then <SPAN CLASS="efeature">another_rectangle</SPAN> would
715 be left as a <SPAN CLASS="ekeyword">Void</SPAN> reference. As a consequence, it is prudent to check to see if
716 the attachment has actually been made before trying to apply features. Applying
717 a feature to a <SPAN CLASS="ekeyword">Void</SPAN> reference will cause an exception. Almost always,
718 assignment attempt will be used in the following manner:</P>
719 <CODE>
720 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN CLASS="efeature">my_polygon</SPAN> := <SPAN CLASS="efeature">my_rectangle</SPAN><BR>
721 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN CLASS="efeature">print</SPAN> (<SPAN CLASS="efeature">my_polygon</SPAN>.<SPAN CLASS="efeature">perimeter</SPAN>)<BR>
722 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN CLASS="efeature">another_rectangle</SPAN> ?= <SPAN CLASS="efeature">my_polygon</SPAN><BR>
723 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN CLASS="ekeyword">if</SPAN> <SPAN CLASS="efeature">another_rectangle</SPAN> /= <SPAN CLASS="ekeyword">Void</SPAN>
724 <SPAN CLASS="ekeyword">then</SPAN>&nbsp;&nbsp;&nbsp;<SPAN CLASS="ecomment"> -- Make sure assignment happened</SPAN><BR>
725 &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN CLASS="efeature">print</SPAN>
726 (<SPAN CLASS="efeature">another_rectangle</SPAN>.<SPAN CLASS="efeature">width</SPAN>)&nbsp;&nbsp;
727 </P>
728 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN CLASS="ekeyword">end</SPAN><BR>
729 </CODE>
730 <P>&nbsp;</P>
731 <P>&nbsp;</P>
732 </BODY>
733 </HTML>


Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

  ViewVC Help
Powered by ViewVC 1.1.23