I am trying to declare an abstract class A
with a constructor with a default behavior: all subclasses must initialize a member self.n
:
from abc import ABCMeta class A(object): __metaclass__ = ABCMeta def __init__(self, n): self.n = n
However, I do not want to let the A
class be instantiated because, well, it is an abstract class. The problem is, this is actually allowed:
a = A(3)
This produces no errors, when I would expect it should.
So: how can I define an un-instantiable abstract class while defining a default behavior for the constructor?
We are also adding an abstract constructor that can be called by its subclasses. To be fair I'm tempted to remove this constructor considering that an abstract class is not supposed to be instantiated. At the same time the constructor can be used as a guidance for the subclasses that will have to implement it.
Yes! Abstract classes can have constructors! Yes, when we define a class to be an Abstract Class it cannot be instantiated but that does not mean an Abstract class cannot have a constructor. Each abstract class must have a concrete subclass which will implement the abstract methods of that abstract class.
A constructor is used to initialize an object not to build the object. As we all know abstract classes also do have a constructor. So if we do not define any constructor inside the abstract class then JVM (Java Virtual Machine) will give a default constructor to the abstract class.
You can't call an abstract class constructor with a class instance creation expression, i.e. As constructors of abstract classes can only be called within subclass constructors (and by chaining one to another within the same class), I typically make them protected ... making them public would serve no purpose.
Making the __init__
an abstract method:
from abc import ABCMeta, abstractmethod class A(object): __metaclass__ = ABCMeta @abstractmethod def __init__(self, n): self.n = n if __name__ == '__main__': a = A(3)
helps:
TypeError: Can't instantiate abstract class A with abstract methods __init__
Python 3 version:
from abc import ABCMeta, abstractmethod class A(object, metaclass=ABCMeta): @abstractmethod def __init__(self, n): self.n = n if __name__ == '__main__': a = A(3)
Works as well:
TypeError: Can't instantiate abstract class A with abstract methods __init__
A not so elegant solution can be this:
class A(object): def __init__(self, n): if self.__class__ == A: raise Exception('I am abstract!') self.n = n
Usage
class B(A): pass a = A(1) # Will throw exception b = B(1) # Works fine as expected.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With