Python 3: pure example for inheritance and abstract methods?

The actual code is very different and generally different, but I felt that this small example might be better, since my problem is understanding the key concepts of complex inheritance scripts (and not in my specific domain).

Consider that we have a base class Entity:

from enum import Enum
from abc import abstractmethod

class Condition(Enum):
    ALIVE = 1
    DEAD = 2
    UNDEAD = 3

class Entity(object):

    def __init__(self):
        self.condition = Condition.ALIVE
        self.position = 0
        self.hitpoints = 100

    def move(self):
        self.position += 1

    def changeHitpoints(self, amount):
        self.hitpoints += amount

    @abstractmethod
    def attack(self, otherEntity):
        pass

This is a base class that inherits other specific objects, and attack()should be abstract, since each object must implement its own attack method.

Now we can implement some objects:

class Orc(Entity):

    def __init__(self):
        super().__init__()
        self.hitpoints = 150
        self.damage = 10

    def attack(self, otherEntity : Entity):
        otherEntity.changeHitpoints(-self.damage)

class Human(Entity):

    def __init__(self):
        super().__init__()
        self.damage = 8

    def attack(self, otherEntity : Entity):
        otherEntity.changeHitpoints(-self.damage)

class Undead(Entity):

    def __init__(self):
        super().__init__()
        self.condition = Condition.UNDEAD
        self.damage = 5

    def attack(self, otherEntity : Entity):
        # harm enemy
        otherEntity.changeHitpoints(-self.damage)
        # heal yourself
        self.changeHitpoints(1)

It works great. However, I am struggling to find a good solution ( DRY- style) for implementing "abilities" and other things.

, Orc Human , , - :

class CanJump(Entity):

    def jump(self):
        self.position += 2

class Orc(Entity, CanJump):
    (...)

class Human(Entity, CanJump):
    (...)

. (1) self.position CanJump, Entity?! , attack() CanJump. , CanJump . (2) , , , , , , Condition.DEAD move(), attack(),... , CanJump self.condition.

?

, ? . UndeadHuman class UndeadHuman(Undead, Human). - (Undead ) attack Undead, CanJump a Human.

+4
2

[W] self.position CanJump, Entity?!

, . CanJump , . , , CanJump position. CanJump Entity. :

class CanJump:
    def jump(self):
        self.position += 2

. :

class Orc(Entity, CanJump):
    (...)

class Human(Entity, CanJump):
    (...)

, :

from abc import abstractmethod


class A:
    def __init__(self):
        self.a = 0 

    @abstractmethod
    def m(self):
        pass


class C:
    def c(self):
        self.a += 1


class B(A, C):
    def __init__(self):
        super().__init__()

    def m(self):
        print('method in B')


b = B()
print(b.a) # 0
b.c()
print(b.a) # 1
b.m() # method in B

, . . CanJump .

, . , , @kindall answer, .

+3

, .

Entity, RaceModifier, / . , :

class RaceModifier:
    def __init__(self):
        ...
        self.abilities = []

class Orc(RaceModifier):
    def __init__(self):
        super().__init__()
        self.extra_hit_points = 50
        self.extra_damage = 2
        self.abilities = [JUMPING]

class Undead(RaceModifier):
    def __init__(self):
        super().__init__()
        self.abilities = [REGEN_ON_ATTACK]

class Entity:
    ...
    def has_ability(self, ability): # ability = JUMPING etc
        for race in self.race_modifiers:
            if ability in race.abilities:
                return True
        for eq in self.equipment: # wearing a ring of jumping ? :)
            if ability in eq.abilities:
                return True
        return False
+1

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


All Articles