I stumbled over the term "inheritable alternative constructors" in this answer: https://stackoverflow.com/a/1669524/633961
The link points to a place where classmethod
gets explained.
Do other programming languages have this feature, too?
I stumbled over the term "inheritable alternative constructors" in this answer: https://stackoverflow.com/a/1669524/633961
The link points to a place where classmethod
gets explained.
Do other programming languages have this feature, too?
One of the things that you can do with ANY language that has class methods (or similar) is provide alternative constructors. A slightly contrived Python3 example below :
class Color():
def __init__( self, red, green, blue):
self._red, self._green, self._blue = red, green, blue
@classmethod
def by_name( cls_, color_name ):
color_defs = {'white':(255,255,255), 'red':(255,0,0),
'green':(0,255,0),'blue':(0,0,255)}
return cls_( *color_defs[color_name] )
with this class you can now do :
red = Color(255,0,0) # Using the normal constructor
# or
red = Color.by_name('red') # Using the alternative
In Python the 'by_name' method would normally be called a factory method, rather than a constructor, but it uses the normal constructor methods.
Because this 'by_name' method is just a classmethod, it means you subclass it, the class method is inherited too - so it can be used on any subclass: i.e. it is inheritable and extensible.
An example in Python of a subclass which extends the Color class above, and extends the constructor and the 'by_name'
class ColorWithAlpha( Color ):
def __init__(self, red, green, blue, alpha=1.0):
super().__init__(red,green,blue)
self._alpha = alpha
@classmethod
def by_name( cls_, color_name, alpha):
inst = super().by_name(color_name)
inst._alpha = alpha
return inst
red_alpha = ColorWithAlpha(255,0,0,0.5)
red2_alpha = ColorWithAlpha.by_name('red',0.5)
Other languages have similar alternative constructors (for instance C++ allows multiple constructors based on the arguments types), and these methods are all inheritable (i.e. subclasses can use them too (or extend them as necessary). I can't speak of other languages, but I am sure other OOP languages will have similar constructors/factory method capabilities.
A Python class can only have one __init__()
method, which many call the class constructor because it's called to initialize instances of the class when they are created by calling the class.
Sometimes it's useful to have other, alternative, ways of creating instances of the class, and functions or methods that do that could collectively be called alternative constructors. Since these will be called before an instance exists, they are often implemented as classmethod
s rather than standalone functions. This also requires the class name (or instance of the class) to be used to make it more obvious what is being done: i.e. MyClass.created_some_other_way()
Like most methods, they will be inherited by any subclasses derived from the class that defines them, so could collectively be referred to as inheritable alternative constructors to emphasize what would otherwise be implicit.
To make clear the inheritable portion of the question, here is the first example rewritten in a way that works if inheritance is not used. Again, this is 'not' what you want to do.
class Color():
def __init__( self, red, green, blue):
self._red, self._green, self._blue = red, green, blue
def by_name(color_name ):
color_defs = {'white':(255,255,255), 'red':(255,0,0),
'green':(0,255,0),'blue':(0,0,255)}
return Color( *color_defs[color_name] )
Note that the @classmethod
is gone, as well as the references to cls_
. Also the return statement calls out the name of the class, Color
, directly.
Using the @classmethod
makes it possible to refer to Color
with the more general and inheritance friendly cls_
.