root/trunk/manuals/userman/inheritance.html

Revision 4621, 11.3 KB (checked in by pmoura, 6 weeks ago)

Improved navigation bar in the XHTML manual pages.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1<?xml version="1.0" encoding="utf-8"?>
2<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
3    "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
4
5<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
6
7<head>
8    <meta http-equiv="content-type" content="application/xml+xhtml; charset=utf-8" />
9    <title>Logtalk user manual: inheritance</title>
10    <link rel="stylesheet" href="../screen.css" type="text/css" media="screen"/>
11    <link rel="stylesheet" href="../print.css" type="text/css" media="print"/>
12</head>
13
14<body>
15
16<div class="top-left">Logtalk user manual</div> 
17<div class="top-right">Inheritance</div>
18<div class="bottom-left"><span class="page"/></div> 
19<div class="bottom-right"><span class="page"/></div>
20<div class="navtop"><a href="../index.html">Contents</a> &gt; <a href="index.html">User Manual</a> &gt; Inheritance</div>
21
22<h1 id="inheritance_inheritance">Inheritance</h1>
23
24<p>
25The inheritance mechanisms found on object-oriented programming languages allow us the specialization of previously defined objects, avoiding the unnecessary repetition of code. In the context of logic programming, we can interpret inheritance as a form of theory extension: an object will virtually contain, besides its own predicates, all the predicates inherited from other objects that are not redefined by itself.
26</p>
27<p>
28Logtalk uses a depth-first lookup procedure for finding predicate declarations and predicate definitions, as explained below. The <a title="Consult reference manual" href="../refman/directives/alias3.html"><code>alias/3</code></a> predicate directive may be used to solve inheritance conflicts and for defining alternative names for inherited predicates.
29</p>
30
31<h2 id="inheritance_protocol">Protocol inheritance</h2>
32
33<p>
34Protocol inheritance refers to the inheritance of predicate declarations (scope directives). These can be contained in objects, in protocols, or in categories. Logtalk supports single and multi-inheritance of protocols: an object or a category may implement several protocols and a protocol may extend several protocols.
35</p>
36
37<h3 id="inheritance_protocol_prototype">Search order for prototype hierarchies</h3>
38
39<p>
40The search order for predicate declarations is first the object, second the implemented protocols (and the protocols that these may extend), third the imported categories (and the protocols that they may implement), and last the objects that the object extends. This search is performed in a depth-first way. When an object inherits two different declarations for the same predicate, by default, only the first one will be considered.
41</p>
42
43<h3 id="inheritance_protocol_class">Search order for class hierarchies</h3>
44
45<p>
46The search order for predicate declarations starts in the object classes. Following the classes declaration order, the search starts in the classes implemented protocols (and the protocols that these may extend), third the classes imported categories (and the protocols that they may implement), and last the superclasses of the object classes. This search is performed in a depth-first way. If the object inherits two different declarations for the same predicate, by default only the first one will be considered.
47</p>
48
49<h2 id="inheritance_implementation">Implementation inheritance</h2>
50
51<p>
52Implementation inheritance refers to the inheritance of predicate definitions. These can be contained in objects or in categories. Logtalk supports multi-inheritance of implementation: an object may import several categories or extend, specialize, or instantiate several objects.
53</p>
54
55<h3 id="inheritance_implementation_prototype">Search order for prototype hierarchies</h3>
56
57<p>
58The search order for predicate definitions is similar to the search for predicate declarations except that implemented protocols are ignored (they can only contain predicate directives).
59</p>
60
61<h3 id="inheritance_implementation_class">Search order for class hierarchies</h3>
62
63<p>
64The search order for predicate definitions is similar to the search for predicate declarations except that implemented protocols are ignored (they can only contain predicate directives).
65</p>
66
67<h3 id="inheritance_implementation_redefinition">Inheritance versus predicate redefinition</h3>
68
69<p>
70When we define a predicate that is already inherited from other object, the inherited definitions are hidden by the new definitions. This is called overriding inheritance: a local definition overrides any inherited ones. For example, assume that we have the following two objects:
71</p>
72<pre>:- object(root).
73
74    :- public(bar/1).
75    :- public(foo/1).
76
77    bar(root).
78
79    foo(root).
80
81:- end_object.
82
83
84:- object(descendant,
85    extends(root)).
86
87    foo(descendant).
88
89:- end_object.</pre>
90<p>
91After compiling and loading these objects, we can check the overriding behavior by trying the following queries:
92</p>
93<pre>| ?- root::(bar(Bar), foo(Foo)).
94
95Bar = root
96Foo = root
97yes
98
99
100| ?- descendant::(bar(Bar), foo(Foo)).
101
102Bar = root
103Foo = descendant
104yes</pre>
105<p>
106However, we can explicitly program other behaviors. Let us see a few examples.
107</p>
108
109<h4 id="inheritance_specialization">Specialization inheritance</h4>
110
111<p>
112Specialization of inherited definitions: the new definition uses the inherited definitions, adding to this new code. This is accomplished by calling the <a title="Consult reference manual" href="../refman/control/super1.html"><code>^^/1</code></a> operator in the new definition.
113</p>
114<pre>:- object(root).
115
116    :- public(init/0).
117
118    init :-
119        write('root init'), nl.
120
121:- end_object.
122
123
124:- object(descendant,
125    extends(root)).
126
127    init :-
128        write('descendant init'), nl,
129        ^^init.
130
131:- end_object.
132
133
134| ?- descendant::init.
135
136descendant init
137root init
138
139yes</pre>
140
141<h4 id="inheritance_union">Union inheritance</h4>
142
143<p>
144Union of the new with the inherited definitions: all the definitions are taken into account, the calling order being defined by the inheritance mechanisms. This can be accomplished by writing a clause that just calls, using the <a title="Consult reference manual" href="../refman/control/super1.html"><code>^^/1</code></a> operator, the inherited definitions. The relative position of this clause among the other definition clauses sets the calling order for the local and inherited definitions.
145</p>
146<pre>:- object(root).
147
148    :- public(foo/1).
149
150    foo(1).
151    foo(2).
152
153:- end_object.
154
155
156:- object(descendant,
157    extends(root)).
158
159    foo(3).
160    foo(Foo) :-
161        ^^foo(Foo).
162
163:- end_object.
164
165
166| ?- descendant::foo(Foo).
167
168Foo = 3 ;
169Foo = 1 ;
170Foo = 2 ;
171
172no</pre>
173
174<h4 id="inheritance_selective">Selective inheritance</h4>
175
176<p>
177Hiding some of the inherited definitions, or differential inheritance: this form of inheritance is normally used in the representation of exceptions to generic definitions. Here we will need to use the <a title="Consult reference manual" href="../refman/control/super1.html"><code>^^/1</code></a> operator to test and possibly reject some of the inherited definitions.
178</p>
179<pre>:- object(bird).
180
181    :- public(mode/1).
182
183    mode(walks).
184    mode(flies).
185
186:- end_object.
187
188
189:- object(penguin,
190    extends(bird)).
191
192    mode(swims).
193    mode(Mode) :-
194        ^^mode(Mode),
195        Mode \= flies.
196
197:- end_object.
198
199
200| ?- penguin::mode(Mode).
201
202Mode = swims ;
203Mode = walks ;
204
205no</pre>
206
207<h2 id="inheritance_types">Public, protected, and private inheritance</h2>
208
209<p>
210To make all public predicates declared via implemented protocols, importeds categories, or inherited objects protected or to make all public and protected predicates private we prefix the entity's name with the corresponding keyword. For instance:
211</p>
212<pre>:- object(Object,
213    implements(private::Protocol)).       % all the Protocol public and protected
214    ...                                   % predicates become Object's private
215:- end_object.                            % predicates</pre>
216<p>
217or:
218</p>
219<pre>:- object(Class,
220    specializes(protected::Superclass)).  % all the Superclass public predicates
221    ...                                   % become Object's protected predicates
222:- end_object.</pre>
223<p>
224Omitting the scope keyword is equivalent to using the public scope keyword. For example:
225</p>
226<pre>:- object(Object,
227    imports(public::Category)).
228    ...
229:- end_object.</pre>
230<p>
231This is the same as:
232</p>
233<pre>:- object(Object,
234    imports(Category)).
235    ...
236:- end_object.</pre>
237<p>
238This way we ensure backward compatibility with older Logtalk versions and a simplified syntax when protected or private inheritance are not used.
239</p>
240
241<h2 id="inheritance_composition">Composition versus multiple inheritance</h2>
242
243<p>
244It is not possible to discuss inheritance mechanisms without referring to the long and probably endless debate on single versus multiple inheritance. The single inheritance mechanism can be implemented in an very efficient way, but it imposes several limitations on reusing, even if the multiple characteristics we intend to inherit are orthogonal. On the other hand, the multiple inheritance mechanisms are attractive in their apparent capability of modeling complex situations. However, they include a potential for conflict between inherited definitions whose variety does not allow a single and satisfactory solution for all the cases.
245</p>
246<p>
247Until now, no solution that we might consider satisfactory for all the problems presented by the multiple inheritance mechanisms has been found. From the simplicity of some extensions that use the Prolog search strategy like <a href="../bibliography.html#McCabe92">[McCabe 92]</a> or <a href="../bibliography.html#Moss94">[Moss 94]</a> and to the sophisticated algorithms of CLOS <a href="../bibliography.html#Bobrow88">[Bobrow 88]</a>, there is no adequate solution for all the situations. Besides, the use of multiple inheritance carries some complex problems in the domain of software engineering, particularly in the reuse and maintenance of the applications. All these problems are substantially reduced if we preferably use in our software development composition mechanisms instead of specialization mechanisms <a href="../bibliography.html#Taenzer89">[Taenzer 89]</a>. Multiple inheritance can and should be seen more as a useful analysis and project abstraction, than as an implementation technique <a href="../bibliography.html#Shan93">[Shan 93]</a>. Logtalk provides first-class support for software composition using <a title="Consult user manual" href="categories.html"><em>categories</em></a>.
248</p>
249<p>
250Nevertheless, Logtalk supports multi-inheritance by enabling an object to extend, instantiate, or specialize more than one object. The current Logtalk release provides a predicate directive, <a title="Consult reference manual" href="../refman/directives/alias3.html"><code>alias/3</code></a>, which may be used to solve some multi-inheritance conflicts. Lastly, it should be noted that the multi-inheritance support does not compromise performance when we use single-inheritance.
251</p>
252
253<div class="footer">
254    <div class="copyright">
255        <span>Copyright &copy; <a href="mailto:pmoura@logtalk.org">Paulo Moura</a> &mdash; <a href="http://logtalk.org">Logtalk.org</a></span><br/> 
256        <span>Last updated on: October 11, 2008</span>
257    </div>
258    <div class="navbottom">
259        <span><a href="predicates.html">previous</a> | <a href="../glossary.html">glossary</a> | <a href="events.html">next</a></span><br/>
260        <span><a href="http://validator.w3.org/check/referer">XHTML</a> + <a href="http://jigsaw.w3.org/css-validator/check/referer">CSS</a></span>
261    </div>
262</div>
263
264</body>
265
266</html>
Note: See TracBrowser for help on using the browser.