Is it right to inherit from built-in classes?

I want to parse the Apache access.log file with python in a specific way, and although I am completely new to object oriented programming, I want to start doing it now.

I am going to create an ApacheAccessLog class, and the only thing I can imagine now is to use the readline method. In this case, it is traditionally correct to inherit the file from the built-in class, so the class will behave exactly the same as the class file itself , or not? What is the best way to do this?

+6
python inheritance oop
source share
6 answers

In this case, I would use delegation, not inheritance. This means that your class must contain the file object as an attribute and call the readline method on it. You can pass the file object in the constructor of the logger class.

There are at least two reasons for this:

  • Delegation reduces binding, for example, instead of file objects, you can use any other object that implements the readline method (it’s convenient to enter duck print here).
  • When inheriting from a file, the open interface of your class becomes excessively wide. It includes all methods defined in the file, even if these methods do not make sense in the case of the Apache log.
+15
source share

I come from the Java background, but I am sure that the same principles apply to Python. As a rule, you should never inherit from a class whose implementation you do not understand and do not control, unless this class has been specifically designed for inheritance. If it was designed in this way, it should clearly describe it in its documentation.

The reason for this is that inheritance can potentially connect you with the implementation details of the class you inherit from.

To use an example from Josh Bloch’s book, Effective Java

If we extended the ArrayList class to be able to count the number of elements that were added to it during its life cycle (not necessarily the number it currently contains), we might be tempted to write something like this.

 public class CountingList extends ArrayList { int counter = 0; public void add(Object o) { counter++; super.add(0); } public void addAll(Collection c) { count += c.size(); super.addAll(c); } // Etc. } 

Now this extension looks like it will accurately count the number of items that have been added to the list, but in reality this may not be the case. If ArrayList implemented addAll by iterating over the provided Collection and calling its addAll interface addAll for each element, we will count each element added through the addAll method twice. Now the behavior of our class depends on the implementation details of ArrayList .

This, of course, is in addition to the inability to use other List implementations with our CountingList class. Plus the disadvantages of inheriting from a particular class, which are discussed above.

I understand that Python uses a similar (if not identical) method to submit a Java method and therefore will be subject to the same restrictions. If anyone could provide an example in Python, I am sure it will be even more useful.

+6
source share

This is perfectly acceptable for inheriting from an inline class. In this case, I would say that you are right for the money.
The journal is a “file” that reports that inheritance is in order.

General rule.
The dog "is" a Russian animal, therefore it is inherited from the animal. "The owner" has "a Russian animal, therefore it is not inherited from the animal.

+1
source share

Although in some cases it is useful to inherit from built-in functions, the real question here is what you want to do with the output and with your large picture design. Usually I write to the reader (which uses a file object) and spits out some data class that I need in order to store the information I just read. Then it’s easy to create a data class that matches the rest of my design.

+1
source share

You should be safe enough to inherit from the "built-in" class, since subsequent changes to these classes are usually compatible with the current version.

However, you should seriously consider that you really want to associate your class with the additional functionality provided by the built-in class. As mentioned in another answer, you should consider (perhaps even prefer) using delegation instead.

As an example of why you should avoid inheritance if you do not need it, you can look at the java.util.Stack class. As Vector expands, it inherits all methods on Vector. Most of these methods violate the contract implied by Stack, for example. LIFO. It would be much better to implement Stack using the vector inside, only exposing the Stack methods as an API. Then it would be easy to change the implementation in ArrayList or something even later, none of which is possible now due to inheritance.

+1
source share

You seem to have found your answer that in this case, delegation is the best strategy. However, I would like to add that, apart from delegation, there is nothing wrong with extending the built-in class, especially if your alternative, depending on the language, is the “monkey patch” (see http://en.wikipedia.org/ wiki / Monkey_patch )

0
source share

All Articles