0

I'm playing around with class inheritance and I'm wondering if its possible to change aspects of an inherited method in the child class without having to rewrite the whole thing?

For example:

class Parent:
    def _init_(self, x):
        self.x = x

    def foo(self):
        a = self.x
        if a > 0:
            forward = True
        elif a < 0:
            forward = False
        return forward

class Child1(Parent):
    def foo(self, y=None, bool=False):
        if bool:
            a = y
        else:
            a = self.x
        super().foo()

class Child2(Parent):
        pass

What I'm looking for is if I called Child1.foo it could reassign the variable a before running through the method, as defined in the parent class. Where a is dependent on the y and bool arguments passed through the rewritten method in Child1:

print(Child1(2).foo(-2, True))
# => False
print(Child1(2).foo())
# => True
print(Child2(2).foo())
# => True

Is this possible, or would I just have to rewrite a new method for each class?

mkrieger1
  • 19,194
  • 5
  • 54
  • 65
  • 1
    yes is possible, you need to extract the part that you want to be customisable into their own method, so each subclass can modify just that part. – Copperfield Mar 22 '21 at 17:50

1 Answers1

2

I think I understand your problem and I have some suggestions for how you can resolve this:

Using "private" methods

For example:

class Parent:
    def __init__(self, x):
        self.x = x

    def _foo(self, a=None):
        a = a if a else self.x * 2  
        
        if a > 10:
            over = True
        else:
            over = False

        return over

    def foo(self):
        return self._foo()

class Child1(Parent):

    def foo(self, y=None, condition=False):

        if condition:
            a = y*2
        else:
            a = self.x*2

        return self._foo(a)

class Child2(Parent):
    pass

In this example, all child classes will inherit the _foo "private" function, where they may or may not receive a value of a.

Using abstract classes

There is another solution to this problem with abstract classes (here is an example of how to do this), where you forces the child class to implement the function foo:

Important

Remembering that in the case of abstract classes, if you do not define the function decorated with @abstractmethod, you will receive an error similar to this TypeError: Can't instantiate abstract class Child2 with abstract methods foo

Example:

Python 2.x

from abc import ABCMeta, abstractmethod

class Parent:
    __metaclass__ = ABCMeta

    def __init__(self, x):
        self.x = x

    def _foo(self, a=None):
        a = a if a else self.x * 2  
        
        if a > 10:
            over = True
        else:
            over = False

        return over

    @abc.abstractmethod
    def foo(self):
        pass

class Child1(Parent):

    def foo(self, y=None, condition=False):

        if condition:
            a = y*2
        else:
            a = self.x*2

        return self._foo(a)

class Child2(Parent):

    def foo(self):
        return self._foo()

Python 3.x

class Parent(metaclass=ABCMeta):

    def __init__(self, x):
        self.x = x

    def _foo(self, a=None):
        a = a if a else self.x * 2  
        
        if a > 10:
            over = True
        else:
            over = False

        return over

    @abc.abstractmethod
    def foo(self):
        pass

class Child1(Parent):

    def foo(self, y=None, condition=False):

        if condition:
            a = y*2
        else:
            a = self.x*2

        return self._foo(a)

class Child2(Parent):

    def foo(self):
        return self._foo()

In both examples you will have the same result by running this:

print(Child1(2).foo(10, True)) // True
print(Child1(2).foo()) // False
print(Child2(2).foo()) // False