10

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?

ruakh
  • 175,680
  • 26
  • 273
  • 307
Jon
  • 185
  • 1
  • 1
  • 8
  • 3
    Inheritance breaks encapsulation? Only when misused... Inheritance is an integral part of Object Oriented Design. – Mooing Duck Feb 18 '12 at 22:56
  • 5
    Inheritance does not break encapsulation. Derived classes do not have access to private members of their base class. The “knock-on” effect is an integral part of OOP; if animals breathe, then it is expected that dogs, cats, humans, … would breathe too. They are not leaking the internal nature of animals; only realizing it. – Douglas Feb 18 '12 at 22:57
  • Googling "Inheritance vs Delegation" and "Inheritance vs Composition" yields some very nice articles on the subject. – Joe Coder Feb 18 '12 at 23:00
  • @ All of the above. You have not answered my question- which is basically "when inheritance breaks encapsulation for the reason of public/protected modifiers, why is delegation any better?" – Jon Feb 18 '12 at 23:03
  • 2
    Unfortunately, we disagree with the premise of your question, which consequently becomes fallacious to us. – Douglas Feb 18 '12 at 23:07
  • 1
    @Jon: Please note that pretty much all your arguments against inheritance also apply to encapsulation. Given the assumption that someone can mistakenly make a protected interfacethat breaks encapsulation (through inheretance) , why are you assuming that the public interface (through delegation) cannot break encapsulation? Your solution is just as flawed as your premise. – Mooing Duck Feb 19 '12 at 00:44
  • This is all subjective (to your definition of Encapsulation) and academic at best. Ultimately is immaterial, since regardless of (yes/no) it has no bearing on the code implementation. – DaniDev Oct 25 '18 at 19:34

4 Answers4

7

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.

Sid
  • 7,511
  • 2
  • 28
  • 41
  • Hence why you should only use inheritance when the subclass IS A superclass for the WHOLE of it's lifetime? If this is satisfied then the subclass should have access to ALL of the super class's attributes/methods? – Jon Feb 18 '12 at 23:05
  • 3
    Inheritance does not break encapsulation, even in a purist sense. If those members were to be encapsulated and not reachable from derived classes, they wouldn't have been public/protected. – Mooing Duck Feb 18 '12 at 23:06
  • 2
    @MooingDuck Take a look at the link in my answer. It is widely acknowledged that inheritance breaks encapsulation in the purist sense. – Sid Feb 18 '12 at 23:10
  • @Jon Well, in general, I think inheritance should be used when there is an "IS A" relationship. Sure you can use delegation but then you don't inherit the methods of the base. If you want the same interface you'd have to write the same methods in the contained class again. – Sid Feb 18 '12 at 23:12
  • 2
    “If a derived class is allowed to access members inherited from a base class, changes in the base class may require maintenance of the derived class as well.” Isn’t that applicable to _any_ consumer of any class if implementation changes are allowed to leak through the interface? I find the arguments in the cited source weak. – Douglas Feb 18 '12 at 23:14
  • 1
    @Douglas The simple reason is that the derived class can manipulate the base class's data directly and that breaks encapsulation. – Sid Feb 18 '12 at 23:20
  • 4
    Derived classes can manipulate the base class’s data directly only when they’re allowed to do so (through the `protected` access modifier). If you’re mislabelling private fields as protected, then it’s your design that’s broken. – Douglas Feb 18 '12 at 23:24
  • 2
    @Douglas The academic argument for "Inheritance breaking encapsulation" is about the ability to have "protected" members AT ALL. The mere idea of being able to do so, even if intentional, is the reason for purists of OOP saying inheritance breaks encapsulation. – Sid Feb 18 '12 at 23:26
  • 1
    When you declare a member as protected, you are effectively committing to expose it as part of the class’s interface – in this case, to a restricted set of consumers (namely, derived classes). The onus is still on the class designer to ensure that protected members do not leak the internal implementation of the class any more than public members do. Yes, misuse of the protected keyword often breaks encapsulation (as acknowledged by the Gang of Four). Proper use of it does not. – Douglas Feb 18 '12 at 23:33
  • "restricted set of consumers"... which the designer of the superclass has no control over which consumers? – Jon Feb 18 '12 at 23:44
  • 1
    The OP asked why those who say "Inheritance breaks Encapsulation" say so. And I mentioned the reason for that. Whether you agree with those who say so or not is a different matter. Not sure why the answer was down-voted. It is an answer to the OP's question. You don't have to agree with "Inheritance breaks encapsulation" or those who say so but it is obviously something well debated as can be found by a simple google search. Down-voting since you don't agree with someone elses' perspective simply shows intolerance. – Sid Feb 19 '12 at 01:33
  • @Sid: I didn’t downvote your answer. I understand that people may have differing opinions on the same definition; you were presenting another perspective. – Douglas Feb 19 '12 at 09:19
  • @Douglas Hey wasn't aimed at you.I inherit classes all the time and it doesn't bother me. Was just explaining the OP the reason people say that. – Sid Feb 19 '12 at 15:38
2

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:

  • Person class might be abstract class OR

  • Person class might be protected inside the same package as Employee

Muhammad Soliman
  • 21,644
  • 6
  • 109
  • 75
2

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.

Alireza Rahmani Khalili
  • 2,727
  • 2
  • 32
  • 33
2

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)

Beatles1692
  • 5,214
  • 34
  • 65
  • But the designer of the super class cannot know every possible class which could extend it? So the privilege given by inheritance can be abused by 6th/7th generation subclasses? – Jon Feb 18 '12 at 23:19
  • 1
    what do you mean by being abused ? when we talk about encapsulation we are talking about the state of a class that can be protected by private modifiers.All the first designer should do it is to make sure that there's no way that any user of that class (by object or by class) use the behavior to left the object in an invalid state – Beatles1692 Feb 18 '12 at 23:35
  • so make ALL attributes of the superclass private, make the methods protected and happy days? – Jon Feb 18 '12 at 23:54
  • and preventing the children from changing the critical behaviors. – Beatles1692 Feb 19 '12 at 00:02
  • 1
    8 years later I am giving vote up for the correct answer(open/closed) – Miroslav Trninic Apr 14 '20 at 19:16