0

suppose I have a class which has 10 methods, (i write pass here, but assume they would have some implementation)

class KlassOne:
    def method_one(self, x):
        pass
    
    def method_two(self, y, z):
        pass
    ...
    def method_five(self, a):
        pass
    ...
    def method_ten(self, b):
        pass 

and a second class which inherits from the first one.

class KlassTwo(KlassOne):
    def method_eleven(self, w):
        pass

but KlassTwo does not want all ten methods of KlassOne, let us say KlassTwo wants to inherit only these four methods,

wanted_methods = [method_one, method_three, method_eight, method_nine]

and the rest are not applicable for KlassTwo one example could be, KlassOne is Person and KlassTwo is Robot and method_five is EatsFood so, our Robot does not want to inherit EatsFood whereas method_one is BodyWeight, and let us assume it makes sense for both Person and Robot, so Robot wants to inherit method_one.

but how could this partial inheritance be achieved???

one way to do this is by using NotImplemented, for example,

class KlassTwo(KlassOne):
    def method_five(self, a):
        raise NotImplemented

and do the same for each method that is not wanted.

or the other way could be to use Composition, like,

class KlassTwo:
    def __init__(self, x):
        self.t = KlassOne.method_one(self, x)

something like that, and only use the methods that are wanted.

but I would like to use inheritance, and completely disable the inheritance of some methods, that is something like,

class KlassOne:
    @not_inheritable
    def method_five(self, a):
        pass

so that no subclass would get method_five. how do I achieve this?

or give a list in KlassTwo, again like,

wanted_methods = [method_one, method_three, method_eight, method_nine]

and ensure that only these get inherited.

apostofes
  • 2,959
  • 5
  • 16
  • 31
  • 2
    If `KlassTwo` does not implement all of its base class' methods, then it's not a proper subclass. I think the best you can do if you want to use inheritance would be to make them do nothing. As the Wikipedia article on [Inheritance](https://en.wikipedia.org/wiki/Inheritance_(object-oriented_programming)) says '"In most class-based object-oriented languages, an object created through inheritance, a "child object", acquires all the properties and behaviors of the "parent object"'. – martineau Apr 13 '22 at 01:20
  • 2
    This is an indication that your parent class is not generic enough. It sounds like it should be split up into two or more interfaces. – Paul M. Apr 13 '22 at 01:38
  • "but KlassTwo does not want all ten methods of KlassOne, let us say KlassTwo wants to inherit only these four methods" then *you don't want inheritance* – juanpa.arrivillaga Apr 13 '22 at 01:48
  • That makes no sense if a class derives from another class, it is expected to inherit all the attributes and methods from the parent class, otherwise, the object design of the solution is wrong. – HuLu ViCa Apr 13 '22 at 01:59

1 Answers1

0

This doesn't directly answer your question of "How to inherit partially", rather is suggesting alternative in case of we're facing a XYZ problem.

Considering your human and robot example, it seems like your base class is not quite a baseline class(or generic) for what you're trying to do.

It might be better to define base class as Union of subclasses you're going to have, and add other Might-need-might-not features like EatsFood in subclass, or as Mixin.

For example, let's say we want to have Human, Humanoids, Monkey and Marcus Wright.

What they have in common: They are human-like entities with human shape. Let's define base class with what usual human-like entities could do.

from __future__ import annotations


class HumanLike:
    """
    Base class for human-like entities
    """

    def __init__(self):
        # some required attributes or setups
        pass

    def left_punch(self, target: HumanLike):
        """punch target with left fist"""

    def right_hook(self, target: HumanLike):
        """Give nice right hook to target"""

    def walk(self, pos):
        """Walk towards pos"""

Now we want to make Human, Humanoids and monkey. Then we can find something common between Human and Monkey, make such as mixin.

class BiologicalMixin:
    """
    Mixin class for biological entities with basic needs
    """

    def eat(self, food):
        """Eats given food"""

    def breath(self):
        """Give that lung a fresh 'n nice air"""


class RoboticMixin:
    """
    Mixin for Non-Biological entities with robot needs
    """

    def recharge(self):
        """recharge energy"""

    def robot_dance(self):
        """Pull out some sick moves that weak creatures can't"""

And then all we have to do would be subclassing these to make various stuffs.

class Human(HumanLike, BiologicalMixin):
    """
    An obviously human like being with biological needs
    """


class Humanoid(HumanLike, RoboticMixin):
    """
    A Human shaped robot
    """


class Monkey(HumanLike, BiologicalMixin):
    """
    They love bananas!
    """


class TerminatorHybrid(HumanLike, BiologicalMixin, RoboticMixin):
    """
    Marcus Wright would be here
    """

This is more common way of inheritance - Inheriting optionally isn't an inheritance.

If you really need such, best bet I can think of is to use composition and map methods you want manually.

jupiterbjy
  • 2,882
  • 1
  • 10
  • 28