In Object Orientation, does an inheritance violate the encapsulation?

4

Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides , write the following statement:

"... inheritance violates the encapsulation."

Below is the paragraph that contains this statement:

  

" ... class inheritance also has some disadvantages. First, you can not change legacy implementations of run-time ancestor classes because inheritance is defined at compile time. place, and generally this is the worst, ancestral classes often define at least part of the physical representation of their subclasses. Because the inheritance exposes to a subclass the implementation details of their ancestors, it is often said that "the inheritance violates The implementation of a subclass in this way becomes so tied to the implementation of its parent class that any change in the implementation of this class will force a change in that. "

I could not visualize this statement in practice. How does the inheritance violate the encapsulation? To further elucidate the understanding, an example that justifies this statement is welcome.

    
asked by anonymous 22.03.2016 / 19:36

4 answers

8

This means that the coupling is strong and any change of code in the base class affects the subclasses.

Therefore, it is not recommended to make the inheritance for reuse of code. Because if a function needs to be changed in the original class, it will affect all daughters, and the easy solution would be to tamper with the encapsulation (making something public or private that makes sense).

In many cases today, we recommend the composition in place of the inheritance to structure a code. The goal is to delegate smaller pieces to a class that is part of the larger class.

For example, creating the Reserve class and the Buy class to be part of the Transaction class. In this case, it leaves all functions well separated and with well-defined behaviors.

    
22.03.2016 / 20:00
4

Inheritance, as taught in OO in the 1990s (at a time when OO was going to end hunger in the world), has surprisingly few legitimate uses. I would not use the phrase "violate the encapsulation", I would say before that the inheritance "engages" the subclasses. Delphi-style "90's" languages, which only had inheritance as a means of code reuse, had deep class hierarchies in their framework (it even came with a chart in the A3-sized product box to paste on the wall), and broke everything down. each new version.

It gets even weirder when multiple inheritance is allowed. That thing of "Square is subclass of Rectangle but also is subclass of Regulatory Polygon" ... there "Circle" should be subclass of "Regulatory Polygon" or not? At least they discovered in the 1990s that multiple inheritance was not a good idea, and the only really legitimate use was adherence to interfaces, ie, simple inheritance of a concrete class and multiple inheritance of purely abstract classes (Java has been this way since always).

Sometimes this plaster is perfectly adequate. In all visual frameworks I know of, each screen control is descended from a View class (UIView on iOS, View on Android, etc.). In this case, inheritance is appropriate because derived views have to conform rigidly to protocols and Base view operation; and the base view implements all of the basic functionality (it is the derivative that will "talk" to the video driver, etc.). If View changes its modus operandi, it is legitimate and desirable to "break" all the derivatives of View, preferably at compile time, to be readapted.

But in most cases this hierarchical inheritance is a bad way to reuse code. Even the inheritance of interfaces is obsolete, the "protocols" of Objective-C / Swift or "duck typing" of interpreted languages, are much better. These languages also allow you to add methods to a class without having to define a subclass ("composition"). These features allow frameworks with "shallow" hierarchies. such as Apple's UIKit: link

In short, overuse of inheritance was a consequence of the limited resources of the available languages, the "novelty" of OO techniques, and the misunderstanding of "real" OO as implemented in Smalltalk.

    
23.03.2016 / 01:33
4

We have to see this discussion from the point of view of encapsulation :

  

A mechanism to restrict access to elements of the class

Encapsulation allows you to create an isolated implementation, so you can test in isolation and ensure that changes to the implementation (without changing the interface) have zero impact on the rest of the system.

The opposite of this, just to give a contrast, is you change a line of code and have to test half the system because of badly coupled bad code.

With this in mind, inheritance violates encapsulation in the sense that change in a superclass has the potential to affect all subclasses.

Think of the case where a superclass is used on multiple projects and now all of them will need to be updated and tested again.

In general, this does not happen if a superclass has private (private) members. On the other hand, when we talk about members that can be accessed by subclasses ( protected , for example) we have to understand that, from the point of view of the subclass, protected and public are the same thing, there was no encapsulation whatsoever.

Finally, using inheritance in the wrong context (not easy to know) takes you quickly from:

  

Look how cool this my "super class" my 10 colleagues can just extend and have almost everything implemented "for free."

To, after some time:

  

Putz! I have to change this abstract class crap again, ask my 10 colleagues to update their implementations, test everything again, and require all system modules to be updated at the same time in production!

    
23.03.2016 / 02:59
3

At times you may end up falling into situations where the inner implementation of the parent class will generate strange behavior when you override some method of it.

Ex: Case that generates Stackoverflow

public class InheritanceOverflow {

  public static class Parent {

    public void foo() {
      bar();
    }

    public void bar() {}
  }

  public static class Child extends Parent {
    @Override
    public void bar() {
      // Não há como saber nesse ponto que o método foo chama o método bar
      // isso irá gerar uma recursão infinita
      foo();
    }
  }

  public static void main(String[] args) {
    new Child().bar();
  }
}

Basically this example breaks the encapsulation because you will have to know what the internal implementation of the parent class will solve this problem.

    
22.03.2016 / 20:03