This is my code:
from abc import abstractmethod
class PlaySongsLyrics:
@abstractmethod
def sing_lyrics(self):
pass
class PlaySongsMusic:
@abstractmethod
def play_guitar(self):
pass
@abstractmethod
def play_drums(self):
pass
class PlayInstrumentalSong(PlaySongsMusic):
def play_drums(self):
print("Bum-bum-bum")
def play_guitar(self):
print("Some guitar solo*")
class PlayRockSong(PlaySongsMusic, PlaySongsLyrics):
def play_guitar(self):
print("Heavy metal guitar solo*")
def sing_lyrics(self):
print("We will, we will rock you")
def play_drums(self):
print("Bum-bum-bum")
Here is the UML diagram I have made but have not done this before:
With Python, you always have the possibility to use Pyreverse. It is far from being perfect but can definitively help you to get more comfortable with class diagrams.
Strictly speaking, there is no interface in your code, but abstract classes:
PlayInstrumentalSong
inherits one of itPlayRockSong
inherits the twoThe inheritance shall be an arrow with a large hollow triangle at the parent side. Here the diagram generated by pyreverse
which corresponds exactly to this logic (abstract operations are shown in italic, and by the way, pyreverse doesn't show the full class as abstract with a name in italic):
The frontier between abstract classes and interfactes are thin, but you could indeed also model these classes as interfaces (considering the abstract python class as programming solution for the UML interface). In this case, the inheritance would be replaced with a realization, i.e. the same hollow triangle, but the line would be dashed.
Your diagram needs therefore improvement because there is neither inheritance nor realization but only simple associations.