Search code examples
pythonmultiple-inheritanceabc

Python 3.7.4: inheriting both ABC and concrete class


I am modelling a game where each move is the throw of a bomb. There is 1 kind of regular bomb and 3 kinds of special bombs. So, I would like to create a class SpecialBomb that serves as an abstract base for those 3 special bomb classes. The idea is for SpecialBomb to inherit from Bomb, but still be unable to instantiate a SpecialBomb object. I tried the following:

class Bomb:
    def __init__(self):
        self.boom = True

class SpecialBomb(Bomb, ABC):
    def __init__(self):
        super().__init__()

class CrossBomb(SpecialBomb):
    def __init__(self):
        super().__init__()

c = CrossBomb()
print(c.boom)
s = SpecialBomb()

The boom attribute was properly inherited in c, but the program raised no error from the fact that I instantiated SpecialBomb. Is there something I am missing when I inherit ABC, or does this happen every time a class inherits both from ABC and a concrete class?


Solution

  • ABCMeta doesn't actually prevent you from instantiating a class unless it has an abstract method. You can wrap the __init__ in SpecialBomb with the abstractmethod decorator to create the behavior you want.

    from abc import abstractmethod, ABCMeta
    
    
    class Bomb:
        def __init__(self):
            self.boom = True
    
    class SpecialBomb(Bomb, metaclass=ABCMeta):
        @abstractmethod
        def __init__(self):
            super().__init__()
    
    class CrossBomb(SpecialBomb):
        def __init__(self):
            super().__init__()
    
    c = CrossBomb()
    print(c.boom)
    s = SpecialBomb()