Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple Inheritance calling order

 A      B
| |   |   |
C D   E   F
| |   |   |
    G     H
      |
      I


user@ubuntu:~/Documents/Python/oop_python$ cat tt.py
class A:
    def call_me(self):
        print("A")

class C(A):
    def call_me(self):
        super().call_me()
        print("C")

class D(A):
    def call_me(self):
        super().call_me()
        print("D")

class B:
    def call_me(self):
        print("B")

class E(B):
    def call_me(self):
        super().call_me()
        print("E")

class F(B):
    def call_me(self):
        super().call_me()
        print("F")

class G(C, D, E):
    def call_me(self):
        super().call_me()
        print("G")

class H(F):
    def call_me(self):
        super().call_me()
        print("H")

class I(G, H):
    def call_me(self):
        super().call_me()
        print("I")


user@ubuntu:~/Documents/Python/oop_python$ python3.2 -i tt.py
>>> i = I()
>>> i.call_me()
A
D
C
G
I

Question> Why B, E, F are not printed?

//            updated based on comments from delnan

user@ubuntu:~/Documents/Python/oop_python$ cat tt.py
class BaseClass():
    def call_me(self):
        print("BaseClass")
    pass

class A(BaseClass):
    def call_me(self):
        super().call_me()
        print("A")

class C(A):
    def call_me(self):
        super().call_me()
        print("C")

class D(A):
    def call_me(self):
        super().call_me()
        print("D")

class B(BaseClass):
    def call_me(self):
        super().call_me()
        print("B")

class E(B):
    def call_me(self):
        super().call_me()
        print("E")

class F(B):
    def call_me(self):
        super().call_me()
        print("F")

class G(C, D, E):
    def call_me(self):
        super().call_me()
        print("G")

class H(F):
    def call_me(self):
        super().call_me()
        print("H")

class I(G, H):
    def call_me(self):
        super().call_me()
        print("I")

user@ubuntu:~/Documents/Python/oop_python$ python3.2 -i tt.py
>>> i = I()
>>> i.call_me()
BaseClass
B
F
H
E
A
D
C
G
I
like image 988
q0987 Avatar asked Jan 08 '12 17:01

q0987


People also ask

What is multiple inheritance?

Multiple Inheritance is a feature of an object-oriented concept, where a class can inherit properties of more than one parent class. The problem occurs when there exist methods with the same signature in both the superclasses and subclass.

How to implement multiple inheritance in C++?

A program to implement multiple inheritance in C++ is given as follows − In the above program, classes A and B are defined. This is given below − Class C inherits from both classes A and B.

How to chain across multiple inheritance hierarchies using super ()?

Using super ().__init__ (**kwargs) in this way to chain across multiple inheritance hierarchies (by following the MRO) means that we cannot have any extraneous or unused keyword arguments. They have to be captured by parameters with the same name in a constructor somewhere in the chain.

Why doesn’t Java support multiple inheritances of classes?

From the code, we see that: On calling the method fun () using Test object will cause complications such as whether to call Parent1’s fun () or Child’s fun () method. Therefore, in order to avoid such complications, Java does not support multiple inheritances of classes.


1 Answers

A common misunderstanding is that super() will call all superclasses methods. It will not. It will call only one of them. Which one is automatically calculated by super() according to some specific rules. Sometimes the one it calls is not an actual super-class, but a sibling. But there is no guarantee that all will be called, unless all of the classes in their turn are using super().

In this case, A and B is not calling super. And if you add it to A, it will in fact call the "missing" classes, but if you add it to B you get an error, because in this particular case, B will end up being the "last" (or first, depending on how you see it) class.

If you want to use super(), the best solution is to have a common baseclass for A and B that implements call_me, but does not call super(). (Thanks to delnan for suggesting that).

However, if you know your class hierarchy, you can call the superclasses methods directly instead of using super(). Note that this in the case above, doesn't mean that every class must call each of it's baseclasses directly. This is therefore not useful in cases where you as a programmer don't have complete control over the class hierarchy, for example if you write libraries or mixin-classes. Then you have to use super().

like image 140
Lennart Regebro Avatar answered Oct 19 '22 08:10

Lennart Regebro