This isn't really an issue about modules. You would have the same problem even if all the classes were in the same file. The problem is that your DataObject class is hard-coded to create an instance of Shape
, and doesn't know that you have subclassed Shape
and want to use that subclass instead. There are two ways around this:
- Document that subclasses must override
createShape
if they want to use their own custom Shape subclass instead ofShape
. This is simple and effective. One downside is that it can be cumbersome to override the whole method if it is long and all you need to change is the name of the Shape class. On the other hand, ifcreateShape
also does other work that also usually needs to be overridden anyway in subclasses, then having to override it is not a big problem. - Parameterize the DataObject/Shape relationship by giving your DataObject class a
shapeClass
class attribute, and use that to instantiate shapes instead of directly referencingShape
.
That is:
class DataObject(object):
# other stuff...
shapeClass = Shape
def createShape(self, type):
# here we create an instance of the second class
new_shape = self.shapeClass(type)
self.m_shape_list.append(new_shape)
Then you can override it more succinctly in the subclass:
class GraphicObject(DataObject):
# other stuff...
shapeClass = MyShape
By pulling Shape
out of the method code and making it a separate attribute, you allow a subclass to override just that part of the behavior. Now calling someGraphicObject.createShape()
will automatically create a MyShape
.
Which approach is better depends on your overall class design, but the factors mentioned above (about whether methods using the paramterized class are likely to need to be overridden anyway in subclasses) are likely to be relevant.