I would like to deepen the topic of multiple inheritance using Python and I usually find examples that are too simple. I love art and I imagined the following problem and I want to understand if multiple inheritance would be a good design solution for it.
Let's suppose we have STL files (meshes) of 3D scanned faces of ancient Greek/Roman sculptures. You can download this kind of files from websites like, for instance, SketchFab.
Let's suppose we can subdivide our meshes into three main categories:
- Complete face, i.e. a face having both eyes and ears, nose, mouth and forehead.
- "Upper" face, i.e. an incomplete/damaged face having both eyes and ears, the upper part of the nose and forehead, so there is no mouth.
- "Lower" face, i.e. an incomplete/damaged face having only the mouth and the lower part of the nose, so no eyes, no forehead in this case.
Other categories might exist, for example, Left face or Right face or we can have just an eye. However, for the sake of simplicity, I would like to consider only the three categories listed above.
Now, we want to compute geometrical quantities for each face like, for instance, eye width, nose length, mouth width, etc. So we need to implement a bunch of methods.
Let's take a look at the table below. Again, for the sake of simplicity, I am using generic names for the methods.
Both the CompleteFace
and UpperFace
objects have method_a
and both objects implement method_a
in the same way. Maybe method_a
could represent the eye width.
The same logic applies to method_b
and method_c
.
The LowerFace
object does not have these methods.
Similarly, both CompleteFace
and UpperFace
have method_d
that represents the same geometrical quantity, however the two objects implement this method using a different algorithm.
method_h
is common to all of the three objects and the method is implemented in same way. For instance, this method allows to compute the area of the mesh by summing the area of the triangles composing the meshes.
method_i
and method_j
are methods implemented only for the CompleteFace
object.
The remaining methods (method_k
, method_l
, etc.) are implemented in the same way by the CompleteFace
and LowerFace
objects but are not implemented for the UpperFace
object.
The question is: what could it be the best design solution for this problem?
Perhaps, multiple inheritance could be used. We create the UpperFace
class and the LowerFace
class. Then, we create the CompleteFace
class which inherits both the UpperFace
and LowerFace
classes.
So, the CompleteFace
class inherits method_a
, method_b
and method_c
and there is no need to modify/override them. While method_d
needs to be overridden. Finally, method_i
and method_j
are added.
This seems to be a good solution, however multiple inheritance is usually considered a dangerous tool, because of problems like the diamond problem.
Is multiple inheritance the right choice for this problem or should be avoided in favor of other solutions based, for instance, on composition?