forked from sergutsan/groovyck
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathd11-inheritance.tex
750 lines (643 loc) · 30.2 KB
/
d11-inheritance.tex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
\section{Inheritance}
\label{sec:inheritance-1}
Repeating code is a bad thing. If the same code is used in more than
one place in a program, that is a disaster waiting to happen. Sooner or
later, one of the copies of the code will be changed (probably to fix
a bug), but not all copies will be changed\ldots and unpredictable things
will happen (never good).
We already know one strategy to prevent code repetition: using methods
inside a class. By enclosing code inside a method, the
programmer can just call the method from any other section of the code
and the same instructions will always be executed (probably with
different values for the parameters). In this section, we will move
one step further to avoid code repetition by using \emph{inheritance} to
prevent code repetition \emph{among} classes.
\subsection{Extending already-existing classes}
\label{sec:extend-alre-exist}
From all the forms of inheritance, the easiest to understand is the
extension of already existing classes. This is done by means of the
keyword \verb+extends+. You can think of this keyword as stating a
``is a'' relationship: you use it to say that objects of your class
are also objects from another class\ldots with something on top.
Let's assume that we had a class \verb+Ebook+,
part of a program to run an electronic book reader. The class would
have
several methods, including some like \verb+nextPage()+,
\verb+prevPage()+, and maybe even \verb+readAloud(int page)+. When the next
version of our electronic book reader comes out, it includes a new
feature to regulate the background light of the screen. At this point
we have at least two options. First, we can add a new method
\verb+setLight(int)+ to the \verb+Ebook+ class to regulate the
background light; however, this method would also be included as part of the
software running in all the ``plain with no light'' e-books.
A second possibility, is to create two different classes,
\verb+Ebook+ and \verb+LightEbook+, each of them being used for a different
hardware; but this would lead to having lot of methods repeated in
both classes (e.g.~\verb+nextPage()+), which is
bad.
There is a third, much better possibility. We can make
\verb+LightBook+ extend \verb+Ebook+, as in the following example code
(JavaDoc comments ommited for the sake of brevity):
\begin{verbatim}
public class LightEbook extends Ebook {
private int lightLevel = 100;
public void setLight(int newLevel) {
this.lightLevel = newLevel;
}
}
\end{verbatim}
You can see that extending a class is very easy: just say that you are
extending it (in this example, ~\verb+extends Ebook+).
From that point on, your class will be able to use all the public methods (and
some more, see below on Section~\ref{sec:protected-keyword}) from
the class that you are extending without the need to implement them
again. In other words, you can call \verb+nextPage()+ on a
\verb+LightEbook+ object exactly in the same way as you would do it
on a \verb+Ebook+ object.
The base class that is extended is called the \emph{parent class} or
\emph{superclass}\footnote{In this context, ``super'' is as in Latin,
meaning ``up''; there are no connotations of big, extra, or more
powerful. Remember that the convention in computing is that general
classes or interfaces are ``up'' and more specific or extending classes
are ``down''.},
while the extending class is called a \emph{subclass}. When there are
many levels of hierarchy (a class extends a class that extends another
class, etc), those classes up in the hierarchy are called
\emph{ancestor classes}, while those down in the hiearchy are called
\emph{descendant classes}.
\paragraph{Everything is an object!}
\label{sec:everything-an-object}
In Java, every class extends class \verb+Object+ or descends from a
class that extends \verb+Object+. \verb+Object+ is a class from the
core Java library that provides a few methods that every other class
can use. The most commonly used is \verb+equals()+, which compares two
objects and returns \verb+true+ if they are the same (according to
some class-specific rules) and \verb+false+ otherwise.
As everything is an \verb+Object+ by default, you do not need to write
it explicitly (\verb+...extends Object+): Java will do it for
you. Programmers must only explicitly say which class they are
extending if they are extending a class that is \emph{not} \verb+Object+.
\begin{verbatim}
public class MyClass { // no need to say "extends Object" here
// ...
}
\end{verbatim}
\paragraph{Final classes}
\label{sec:final-classes}
You remember that we could use the keyword \verb+final+ to indicate
that a variable holds a constant value, i.e.~that the variable could
not be changed. In a similar way, we can use \verb+final+ to tell the compiler
that a class cannot be changed either. A class defined as \verb+final+
cannot be extended; trying to do so will result in an error at compile
time.
\subsection{Top-down inheritance}
\label{sec:top-down-inheritance}
We have already seen that we can use \emph{interfaces} to specify what a
class is like or, in other words, what is its behaviour, i.e.~the methods
that are public and can be used by other classes. For example, we may
have an interface \verb+Animal+ that was implemented by classes
\verb+Dog+, \verb+Human+, and \verb+Horse+. The interface may define
methods like \verb+move()+, \verb+makeSound()+, and
\verb+breath()+. The three classes would each implement each method.
It is quite possible that the implementations of movement and
sounds are quite different, but on the other hand it seems likely that
\verb+breath()+ is very similar (or exactly the same) in the three
classes. As we know, repetition of code is bad: if we have a bug
in the \verb+breath()+ method, we will be in trouble if we forget to
fix it in all classes. It would be much better if we could have the
same method in just one place so that each class could use it, in the
same way that the code in a method can be used from anywhere in the
class.
In cases like this one, it would be great if we could put the
real code in the interface, not just the declaration; then, all
classes would have it\ldots Well, it turns out we can do something like
that in Java. Although we cannot write any code in an interface,
we can transform the interface into an \emph{abstract class}, and then
make the other classes \emph{extend} it. Let's see an example: assuming
that the original interface looked like this (JavaDoc comments ommited
for the sake of space):
\begin{verbatim}
public interface Animal {
void move(int meters);
String makeSound();
void breath(int air);
}
\end{verbatim}
\ldots if we implement the method \verb+breath()+, the resulting
abstract class could look like this:
\begin{verbatim}
public abstract class Animal {
private int oxygen = 0;
public abstract void move(int meters);
public abstract String makeSound();
public void breath(int air) {
this.oxygen += air / 4;
}
}
\end{verbatim}
As you can see, there are many differences between an interface and an
abstract class:
\begin{itemize}
\item First and foremost, an interface never contains any actual code,
while an abstract class ---like any other class--- can contain real
implementation, i.e.~statements that perform some actions.
\item Interfaces are \emph{implemented}, while abstract classes are
\emph{extended}.
\item All methods in an interface are by definition public and
abstract (i.e.~without actual code), so there is no need to write it
down (but it can be done). On the other hand, methods in an abstract
class can be private or public, abstract or not, and it must be said
explicitly for each of them (see \verb+move(int)+, for example).
\item Abstract classes can contain mutable fields. All fields on an
interface are by definition static and final (i.e.~constant).
\end{itemize}
There are also some similarities:
\begin{itemize}
\item Both abstract classes and interfaces can be used as data
types to \emph{declare} a variable of a complex type
(e.g.~\verb+Animal indiana = new Dog()+).
\item Neither can be used to \emph{instantiate} an object using \verb+new+
(because neither contains a full ``blueprint'' of what the new
object would look like, e.g.~\verb+new Animal()+ is not valid).
\end{itemize}
\subsection{Bottom-up inheritance}
\label{sec:boot-up-inher}
Sometimes, inheritance is a consequence of the design of your
program: you have an interface (e.g.~\verb+Animal+)
that is implemented by several classes (e.g.~\verb+Horse+, \verb+Dog+)
and then decide to add a little code into it and turn it into an
abstract class.
Sometimes it happens the other way around: you have two or
more classes that are apparently unrelated, and then realise that they
have the same code. At this point you want to move the code ``up'' to
an abstract class. For example, imagine that we had a class
\verb+ManorHouse+ and another class \verb+Castle+, initially unrelated
in the design of our program:
\begin{verbatim}
public class ManorHouse {
private Gate gate;
// ...
public void closeForTheNight() {
gate.moveInwards(90);
gate.getLock().setLocked(true);
}
// ...
}
(...)
public class Castle {
private Gate gate;
// ...
public void closeForTheNight() {
gate.moveInwards(90);
gate.getLock().setLocked(true);
}
// ...
}
\end{verbatim}
Code repetition is bad. As soon as we realise that both classes have
the same method, such method should be put in a parent class:
\begin{verbatim}
public abstract class GateGuardedBuilding {
private Gate gate;
// ...
public void closeForTheNight() {
gate.moveInwards(90);
gate.getLock().setLocked(true);
}
}
(...)
public class ManorHouse extends GateGuardedBuilding {
// ...
}
(...)
public class Castle extends GateGuardedBuilding {
// ...
}
\end{verbatim}
Now the method \verb+closeForTheNight()+ is available to both
\verb+ManorHouse+ and \verb+Castle+ because they are extending
the parent (abstract) class \verb+GateGuardedBilding+.
Clear? Not so easy\ldots There are situations in which
this ``repetition of code'' is not straighforward. Look at the
following simplified example:
\begin{verbatim}
public class DrinkRefrigerator {
// ...
public int buyCan(int money) {
if (money < price) {
return money;
}
int change = money - price;
releaseCan();
return change;
}
// ...
}
(...)
public class ChocBarVendingMachine {
// ...
public int getBar(int moneyGiven) {
if (moneyGiven < price) {
return moneyGiven;
} else {
giveChocolateBar();
int change = moneyGiven - price;
return change;
}
}
// ...
}
\end{verbatim}
Although it may not seem at first that a \verb+DrinkRefrigerator+ and
a \verb+ChocBarVendingMachine+ have much in common, an analysis of the
code of methods \verb+buyCan()+ and \verb+getBar()+ shows a strong
similarity, suggesting that the code should be abstracted away to a
parent class. How would it look like? Maybe something similar to this:
\begin{verbatim}
public class Sale {
public boolean sold; // public fields because it does not
public int change; // have methods
}
(...)
public abstract class VendingMachine {
// ...
public Sale buy(int money, int price) {
Sale result = new Sale();
if (money < price) {
result.sold = false;
result.change = money;
} else {
result.sold = true;
result.change = price - money;
}
return result;
}
// ...
}
(...)
public class DrinkRefrigerator extends VendingMachine {
// ...
public int buyCan(int money) {
Sale sale = buy(money, price);
if (sale.sold) {
releaseCan();
}
return sale.change;
}
// ...
}
(...)
public class ChocBarVendingMachine extends VendingMachine {
// ...
public int getBar(int money) {
Sale sale = buy(money, price);
if (sale.sold) {
giveChocolateBar();
}
return sale.change;
}
// ...
}
\end{verbatim}
The code in the subclasses is shorter and clearer because all the hard work
is done in the code that has been abstracted and put in the parent
class. If this code was more complicated and involved several
comparisons or long intrincated calculations, the benefits would be
even greater.
In this second example, it is important to note
that the ``repeated'' methods had two effects: a return value
(to give change) and a side effect (release can or chocolate bar). Because of
this, we needed to create a new intermediate class \verb+Sale+ ---with
no methods--- in order to be able to return two values from the new
method \verb+buy()+. Remember that methods can only return one value;
the only way they can return more is by using a complex type to
encapsulate them all.
\subsection{Visibility revisited}
\label{sec:protected-keyword}
As it evolves and grows, a program can become really complex, usually
beyond of what its programmer(s) can cope with. We know that one of
the basic strategies to keep complexity under control is by hiding
information.
Information is hidden by making it not visible: visible fields can be
read and written, but non-visible fields cannot; visible methods can
be called, but non-visible fields cannot. We have used two keywords
to control the visibility of our classes' fields and methods:
\verb+public+ and \verb+private+. Although these two keywords will
cover most of your needs as a programmer, it is good to know that
there are four levels of visibility in Java: public, protected,
default (package), and private.
\subsubsection{Public}
\label{sec:public}
Public fields are visible for any other class, and can be read and
written accordingly. Letting other classes (even classes that you have
written yourself) to modify
the fields of your classes can have unpredictable effects in a
normal-size program, and that is why you should make all your fields
private as a rule of thumb. The only exception are the fields of
method-less just-used-as-intermediate-data classes (like \verb+Sale+
in the former section).
Public methods are visible to other classes and define the public
interface of your class. This is usually made explicit by implementing
one or more Java interfaces. Note that there is an ambiguity in
natural language here: the public methods of a class are its ``interface''
in the sense that they define how other classes can interact with it,
but that does not necessarily mean that the class \verb+implements+
(in the Java sense) a explicit Java \verb+interface+ defined in a
\verb+.java+ file. You should keep this distinction clear when you
read the documentation of software projects as both meanings of the
words are sometimes used without much care.
\subsubsection{Protected}
\label{sec:protected}
Protected fields and methods are visible for classes in your package
(i.e.~the same folder/directory as the class) and for descendant
classes. There are a few cases in which the distinction
\verb+protected+ vs. \verb+public+ makes sense (i.e.~in event-oriented
architectures) but in most cases this nuance is not worth the
additional complexity, and that
is why many of the most recent programming languages do not include a
\verb+protected+ visibility, only \verb+public+.
As a rule of thumb, use always public if you want other classes to
call the methods in your class. On the other hand, it is important to understand
what \verb+protected+ means because you will find it often when you
read Java code, especially if it is old legacy code.
\subsubsection{Default (i.e.~package)}
\label{sec:default-i.e.-package}
% TODO: add note about package here, conditional on whether the note
% on the TDD lecture is before of after
When the visibility of a field or method is not specified, its default
visibility is ``package-wide'', i.e.~it is visible to other classes in
the same package. There is not a keyword for declaring ``package''
visibility: fields and methods of unspecified visibility become
visible for other classes in the same package.
Up to now, you have not noticed any difference
between \verb+public+ visibility and default visibility because all
your interacting classes have been part of the same package or were
part of the standard Java library (e.g.~String) and you used only
their public methods.
When Java was originally created, making things visible to the same
package seemed like a good idea for several reasons. However, things
have changed over the years and it is very rare today to find a
situation where ``package'' visibility makes sense but \verb+public+
visibility does not, with the additional complexity of keeping track
and what is visible at which level. Therefore, you will very rarely
find default visibility in Java code for a good reason; on the
contrary, it is almost
always a symptom of sloppy programming, a sign of a programmers not
thinking properly about the design of their program or --even worse---
not understanding the difference between \verb+private+ and default
visibility.
\subsubsection{Private}
\label{sec:private}
Private fields and methods are only visible inside their own class. This
is the most complete form of ``hiding'', and should be the default
option for all the fields and most of the methods (unless they are
defined in an interface, i.e.~they are useful for other classes).
Note that \verb+private+ only determines visibility between \emph{classes},
not between \emph{objects}. Objects of the same class are able to see each
other fields and methods. This is very evident in most implementations
of the \verb+.equals()+ method.
\begin{verbatim}
public class Integer {
private int value;
// ...
public boolean equals(Integer other) {
if (this.value == other.value) {
return true;
} else {
return false;
}
}
}
\end{verbatim}
Although the field \verb+value+ is private and cannot be seen from any
other class, any object of class \verb+Integer+ can see the
\verb+value+ method of other objects of the same class.
\subsection{Changing behaviour, overriding methods}
\label{sec:chang-overr-behav}
Extending a class is a way of reusing part of its code in the form of
its public methods. However, there are cases in which by extending a
class you are inheriting a method you do not want. For example, your
class \verb+Employee+ may inherit from class \verb+Person+ a method
\verb+equals()+ that says that two objects are the same person if they
have the same passport number; however, you want your employee-objects
to represent the same employee if they have the same national
insurance number. When this happens, you have to \emph{override} the
method.
Overriding a method is trivially easy: just write the method
again. Java will automatically use the most specific version of the
method when the method is called. Methods \verb+equals()+ and
\verb+hashcode()+, from class \verb+Object+, are typical examples of
methods that are overriden by many classes.
\begin{verbatim}
@Override
public boolean equals(Object other) {
// ... different code here to establish equality
}
\end{verbatim}
The \verb+@Override+ annotation\footnote{We will see more about
annotations in a week, when we start doing automated testing. For
now, you just need to know that they are added just before the
method declaration and start with a @ sign. } is optional, but it is a good idea to
always use it. This will make it evident to other programmers
that the method is overriding a
method from an ancestor class.
% TODO: Remove Footnote
\paragraph{Final methods}
\label{sec:final-methods}
In the same way that we can declare a class to be \verb+final+ so that
it cannot be extended, we can declare a method as \verb+final+; this
will prevent the method from being overriden.
If a class is final, then all its methods are final too.
The opposite is not true: a class with all its method
marked as final can still be extended (even if the existing ones
cannot be overriden, it is always possible to add new methods as long
as the class is non-final).
\subsection{The keyword super}
\label{sec:keyword-super}
There are few keywords in Java that we have not seen yet, but one that
is extremely relevant when we talk about inheritance is
\verb+super+. This keyword designates the \emph{superclass} or
\emph{parent class}, and can be used to use methods defined in it, as
in this trivial example:
\begin{verbatim}
/**
* This method does exactly the same as the method of the same
* name of the parent class, plus printing a message on screen.
* /
@Override
public void someMethod() {
super.someMethod();
System.out.println("Calling someMethod() at subclass.");
}
\end{verbatim}
In practice, calling methods from the superclass is not something that
is used very often (there are some exceptions, but few and far
between).
The only situation in which it is common to use \verb+super+ to call
methods from the parent class ---and it is important to understand
it--- is when the keyword is used to call the constructor of the parent class
inside the constructor of the subclass. This is so important that it must be
done at the first line of the constructor:
\begin{verbatim}
public MyClass() { public MyClass(arguments) {
super(); super(arguments);
// rest of method here... // rest of method here...
} }
\end{verbatim}
If you try to do anything ---like initialising your fields--- before
the \verb+super(...)+ constructor is called, you will get an error
from the Java compiler.
\subsubsection*{Java magic constructors and the hidden super()}
\label{sec:hidden-super}
As this point, you may be wondering how was it possible that you have
created all your classes until now without calling \verb+super()+. The
answer is that Java makes a little bit of magic behind the scenes:
Java can add a default constructor to your classes and/or it can call
the \verb+super()+ constructor even if you forget to use it.
\paragraph{Default constructor}
\label{sec:default-constructor}
Every Java class must have \emph{at least one} constructor method. If your
class does not have an explicit constructor, Java will add one like
this:
\begin{verbatim}
public NameOfMyClassHere() {
super();
}
\end{verbatim}
This constructor does not do much (just calls the superclass'
constructor) and has no parameters. If you do not add your own
constructor to your classes, they will at least have this one. On the
other hand, as soon as you add a constructor to a class Java will see
it, and will not add the default constructor in that case.
\paragraph{Default call to the parent class' constructor}
\label{sec:default-call-parent}
The first thing that every constructor must do is calling the parent
class' constructor. The parent class constructor must always be
executed before the current class constructor starts to do
anything. In other words, a \verb+Dog+ is an \verb+Animal+, but it
becomes an \verb+Animal+ first (e.g.~initialises legs and eyes) and a
\verb+Dog+ later (e.g.~sets sound as barking and smell sensititivy to
a high value).
If the first line in one of your constructor methods is not a call to
one of the superclass' constructors, Java will automatically add a
call to the default parameter-less constructor: \verb+super()+. If
your parent class does not have a parameter-less constructor (either
explicit of magicaly added), the Java compiler will complain.
\subsection{Only one mother(-class)}
\label{sec:limits-inheritance}
A class can only extend another one class. In other words, every Java
class has one and only one parent class (usually \verb+Object+).
If a class could extend two different classes, it may potentially
inherit two methods with the same signature. For example, both parents
may implement a \verb+getName()+ or \verb+equals()+ method in
different ways. Which implementation should be inherited by the
subclass\footnote{This is known in computing as the \emph{diamond
problem}.}?
Some programming languages allow \emph{multiple inheritance},
(extending several classes), and have rules that determine what to do
in the case of method clashes. These rules are not always clear or
intuitive, and can be source of confusion and bugs. The Java creators
considered (probably correctly) that the benefits of multiple
inheritance did not overcome its shortcomings, and Java is thus a
\emph{single inheritance} language, where every class extends one and
only one class.
On the other hand, a class can implement an arbitrary number of
interfaces. As interfaces do not contain any implementation, it is not
a problem to implement two interfaces that declare the same method: any
implementation of that method will satisfy both
interfaces\footnote{Some people use the argument of implementing
several interfaces in Java to say that Java allows for a ``special''
or ``limited'' form of multiple inheritance. I think it is clearer
to use the term inheritance exclusively for those cases
in which actual code is
actually \emph{inherited} from another class. }.
\section{Final note: composition vs. inheritance}
\label{sec:final-note:-comp}
Inheritance is a form of code reuse, but it is not the only one, nor
is it the most adequate in any situation; there are many more. In
Java, the most common forms of code reuse are \emph{inheritance} and
\emph{composition}. Although we will learn more about these topics in
the next module (Object-Oriented Design and Programming), it is good
to have a fair understanding of the basics.
Inheritance establishes an ``is-a'' relationship (e.g.~a dog is-an
animal), and is implemented by
using the keyword \verb+extends+\footnote{We can compare this to
interfaces, which define a ``behaves-as-a'' relationship and are
implemented by using the keyword \emph{implements}.}.
When a class extends another class,
it gets access to all its public and protected fields and methods.
Composition establishes a ``has-a'' relationship (e.g.~a dog has a leg
and has cells), and is implemented by including the ``contained''
classes as types of fields of the ``container'' class. When a class
contains some other class/es it gets access to all its/their public methods
and fields.
Both compositition and inheritance give access to the functionality of
another class. Which is the right approach in each situation?
A first
question that a programmer should ask is whether there is an ``is-a''
or a ``has-a'' relationship between the classes. For example, both
\verb+Animal+ and \verb+Cell+ potentially have a method
\verb+breath()+ that a class \verb+Dog+ may reuse, but it is clear
that a dog is an animal but it is not a cell. However, the answer to
this question is not
always clear-cut. If you have a class \verb+Pound+, a class
\verb+Currency+, and a class \verb+Coin+, which one extends which one?
Is there any \verb+extends+ relationship at all? The final answer
depends on many factors that depend on the specifics of the source
code involved, but it is important to understand that inheritance and
composition are very different approaches.
\paragraph{Only one extension}
\label{sec:only-one-extension}
The first difference is very obvious. In Java you can only extend one
class, but can include as many classes as you want as fields, even
having many fields of the same class.
\paragraph{Flexibility }
\label{sec:flexibility-}
Another difference that is not obvious at first sight is that
inheritance relationships are difficult to change, which can
become problematic when the requirements
of the project change in the future\footnote{And you can bet the farm
that they will. I still have to find a project in which the
requirements were not only clear at the beginning (and there are
\emph{very few} of those) but that they remained constant until the end.};
on the other hand, composition is
easier to modify. Type hierarchies defined by \verb+extends+ become
very rigid over time: changing one of the classes in the hierarchy
tree usually involves changes in many other classes in different parts
of the source code. In other words, type hierarchies provide structure
to the code, but increse its \emph{coupling} (dependance between
classes); a high coupling is bad because its makes the code more
difficult to change and modify\footnote{Some people refer to this as a
code of \emph{high viscosity}. }.
Composition, on
the other hand, provides more flexibility. Changes to the classes
inside a class are typically invisible to all other classes (they are
\verb+private+ fields) so the disruption of the code is contained.
\paragraph{Additional baggage}
\label{sec:additional-baggage}
An additional difference is that inheritance brings more baggage than
composition. Take the example of a class \verb+DancePairMaker+, that
takes names of people in pairs and then prints them. Pairs of names
is something similar to a \verb+Map+, and adding pairs sounds like
\verb+Map.put(String,String)+\ldots so we would like to reuse that
code in \verb+Map+ without the need to write it all again.
If \verb+DancePairMaker+ \emph{includes} a
\verb+Map+, it will use the method \verb+put()+ and nothing
else (there is no need to remove dance pairs: just adding and
printing).
However, if \verb+DancePairMaker+ extends a \verb+Map+, other
classes may be able to \verb+remove()+ pairs because this method is
inherited from the \verb+Map+.
Maybe this is not what the programmer wanted at the time of extending
\verb+Map+, but that is a consequence of extension.
For these two reasons, and some other minor ones, the rule of thumb is
``composition works better than inheritance''. If you find yourself
thinking about extending a class, think twice in case it is better to
include the class instead. (Of course,
you should still abstract repeated code to parent classes, as
explained in Section~\ref{sec:boot-up-inher}).
% \item composition better than extension
%%% Local Variables:
%%% mode: latex
%%% TeX-master: "d11"
%%% End: