People say inheritance breaks encapsulation, which i agree with. They say delegation is better- although the modifiers in delegation can also be public/protected.
So is the real reason why inheritance breaks encapsulation because of the "knock-on" effect of the public/protected modifiers from the super class being exposed to any new classes which extend the current subclass?
Yes. Since it gives the derived class access to members of the base class (depending on what language and which kind of inheritance) it is said that it breaks encapsulation. IMHO this is only if you are clinging to encapsulation in the strictest terms. IMHO it is reasonable to say that you are accepting the derived class as an extension of the base and therefore related in some way and not really breaking the encapsulation.
Purists will disagree with this.
Take a look at http://www.ccs.neu.edu/research/demeter/papers/context-journal/node17.html and search for "breaks" for an academic explanation.
I think from my point of view it breaks in case of addition of new methods in base or super class. If A
is a subclass of B
, even if A
is not modified in any way, a change in B
can break A
. (This is called the Ripple Effect)
Example: Suppose A
overrides all methods in B
by first validating input arguments in each method (for security reasons). If a new method is added to B
and A
is not updated, the new inherited method would introduce a security hole.
To get rid of pitfalls in inheritance, favor or use “Composition” Instead of Inheritance, simple aggregation instead of inheritance , below is an example:
Imagine two classes, Person
and Employee
. Instead of asking Employee
to inherit from Person
, you can compose Person
inside Employee
and forward the requests for Person
functionality to the composed class So We still get the benefit of reusing Person
class.
Notes:
It depends how we design our class.While designing a class We should have the Open-Closed principle in mind .When we are talking about encapsulation we are talking about modification and when we are talking about inheritance we are talking about extending our application then we ,as designers , should choose what we should protect against modification ( using private modifiers in our class ) thus encapsulate our class and what's the open side of our class that is reserved for future extension.(protected membmers).(Think of it as partial concept in .net languages that each class can be separated to different files thus some of them can be extended by the programmer and some others are generated using code generation tools)
imagine:
class A {
void foo(){
...
this.bar();
...
}
void bar(){
...
}
}
class B extends A {
//override bar
void bar(){
...
}
}
class C {
void bazz(){
B b = new B();
// which bar would be called?
B.foo();
}
}
As you see in bazz
method which bar
will be called? the second one the bar
in class B will be called. but, what is the problem here? the problem is foo
method in class A will not know anything about the override of bar
method in class B, Then your invariants may be violated. because foo may expect the only behavior of bar method that is in own class, not something is overridden. This problem is called fragile base-class problem.