Search code examples
pythonmultiple-inheritance

Is it possible to call function from second class with same name in multiple inheritance


Lets say we have three classes

class Father:
    def __init__(self, father_name) -> None:
        self.father_name = father_name

    def name(self):
        print(f"Father name : {self.father_name}")

class Mother:
    def __init__(self, mother_name) -> None:
        self.mother_name = mother_name

    def name(self):
        print(f"Mother name : {self.mother_name}")

class Son(Father, Mother):
    def __init__(self, father_name, mother_name):
        Father.__init__(self, father_name)
        Mother.__init__(self, mother_name)

me = Son('Jamie', 'Jack', 'Linda')
me.name()

The output is :

Father name : Jack

How do I call name method from Mother class instead of Father class without changing the function name so the output would be :

Mother name : Linda


Solution

  • There is a bunch of problems in your code.

    • Your example is not working.
    • Instead of:
        Father.__init__(self, father_name)
        Mother.__init__(self, mother_name)
    

    You should use:

        super(Father, self).__init__(self, father_name)
        super(Mother, self).__init__(self, mother_name)
    

    (Assuming you really want to have inheritance here)

    • Father's name method is called because of something called MRO (method resolution order). Worth a read, but not something you should try to modify. If you only ever want to call Mother's name and not Father's, it's a simple matter of saying Son(Mother, Father) instead of Son(Father, Mother)

    • As mentioned by @Mark, this is not a reasonable use case for inheritance. Child has parents, not is parents.

    All in all, if you want to do it with inheritance, that's what I'd suggest:

    class Son(Mother, Father):
        def __init__(self, father_name, mother_name):
            super(Father, self).__init__(self, father_name)
            super(Mother, self).__init__(self, mother_name)
        def name(self, ParentClass):
            return super(ParentClass, self).name()
    
    me = Son('Jack', 'Linda')
    me.name(Mother)
    me.name(Father)
    

    But, I think a much more reasonable way is using attributes.

    class Son():
        def __init__(self, father_name, mother_name):
            self.father = Father(father_name)
            self.mother = Mother(mother_name)
    
    me = Son('Jack', 'Linda')
    me.mother.name()
    me.father.name()
    

    Or, even better, create a Son with already existing Parent objects. That way you can create multiple people with same parents.

    class Son():
        def __init__(self, father, mother):
            self.father = father
            self.mother = mother
    
    mother = Mother('Linda')
    father = Father('Jack')
    
    me = Son(mother, father)
    me.mother.name()
    me.father.name()