Class Inheritance: Should Constructors Be Compatible? case of multiple inheritance?

One of the recommended principles of object-oriented programming is the Liskov substitution principle : a subclass should behave the same as its base class (warning: this is actually not a correct description of the Liskov principle: see PS).

Is it also recommended to use constructors? Basically, I mean Python and its __init__() methods, but this question applies to any object-oriented language with inheritance.

I ask this question because it is sometimes useful to inherit a subclass from one or more classes that provide nice default behavior (for example, inheritance from a dictionary in Python, so obj['key'] works for objects of the new class). However, it is not always natural or simple to allow the use of a subclass in the same way as a dictionary: sometimes it would be better that the constructor parameters apply only to a specific user subclass (for example, a class that is a set of serial ports can behave like a dictionary with ports['usb1'] , which is USB port # 1, etc.). What is the recommended approach to this situation? having subclass constructors that are fully compatible with the constructions of their base classes and generate instances using the factory object function, which takes simple, user-friendly parameters? or just write a class constructor, the set of parameters of which cannot be directly set to the constructor of its base classes, but which is more logical from the user's point of view?

PS : I misinterpreted the Liskov principle, above: the Sven comment below indicates that subclass objects should behave like superclass objects (the subclass itself should not behave like a superclass, in particular, their constructors should not have the same parameters [signature]) .

+4
source share
1 answer

As requested, I am sending as an answer what was previously a comment.

The principle defined in a related Wikipedia article states: "if S is a subtype of T, then objects of type T can be replaced by objects of type S." He does not read "a subclass should behave the same as its base class (s)." The difference is important when thinking about constructors: the Wikipedia version only talks about subtype objects, not the type itself. A constructor has already been called for an object, so the principle does not apply to constructors. This is also how I use it, and how to use it in the standard lib (e.g. defaultdict and dict ).

Multiple-inheritance constructors probably cannot be discussed in an agnostic language. There are two approaches to Python. If the inheritance diagram includes diamond patterns, and you need to make sure that all constructors are called exactly once, you must use super() and follow the pattern described in the Practical Tips section of Raymond Hettinger's Python super() is considered super . If you don't have diamonds (other than those that include object ), you can also use explicit base class calls for all base class constructors.

+4
source

Source: https://habr.com/ru/post/1392505/


All Articles