Suppose I have a parent class and multiple child classes, which extend the parent class by including more specific information about the ideas they represent. For example:
class Shape:
def __init__(self, center):
self.center = center
class Square(Shape):
def __init__(self, center, side_length):
super().__init__(self, center)
self.side_length = side_length
self.area = side_length ** 2
class Circle(Shape):
def __init__(self, center, radius):
super().__init__(self, center)
self.radius = radius
self.area = 3.14 * (radius ** 2)
Suppose I want to implement a method such as translate(new_center)
in the parent class, which would return a new object with a different center location than the original object. Because all child classes should behave the same way (i.e. the attribute self.center
should change), it makes sense to implement translate()
as a method of the parent class Shape.
If I want to return a new object of type Shape
every time translate()
is called, we can simply define translate()
as a method of Shape
like so:
def translate(self, new_center):
return Shape(new_center)
However, if any child class instances call this method, the result will be of type Shape
, and thus any additional state information contained by the original instance, such as side_length
and area
for a Square
, will be lost. Additionally, translate()
cannot be defined as
def translate(self, new_center):
return self.__class__(new_center)
because the constructors for each of the child classes require additional arguments that the parent class constructor doesn't. How can I implement this without having to override the parent method in each of the child classes (avoiding which was the entire point of defining the parent method)?
You could copy the object and modify the copy:
import copy
class Shape():
def __init__(self, center):
self.center = center
def translate(self, new_center):
new_shape = copy.copy(self) # Replace with deepcopy if needed
new_shape.center = new_center
...