Vererbung mit Komposition Python

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Sirius3
User
Beiträge: 18272
Registriert: Sonntag 21. Oktober 2012, 17:20

@__blackjack__: das merkt man ja, wenn das `art`-Attribut noch fehlt, dann ist die Oberklasse `Tierart` überflüssig. Das allgemeine Problem an künstlichen Anwendungen, wenn die Komplexität nicht durch die Aufgabe gegeben ist.
Benutzeravatar
__blackjack__
User
Beiträge: 14052
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Mit Klassenattribut für die Tierart und mit `attr`-Modul um sich Tipparbeit zu sparen und eine lesbare `__repr__()`-Darstellung zu bekommen:

Code: Alles auswählen

#!/usr/bin/env python3
from attr import attrib, attrs


@attrs
class Tier:
    ART = None
    name = attrib()
    einlieferungsdatum = attrib()
    id = attrib()

    @property
    def art(self):
        return self.ART


@attrs
class Tierheim:
    name = attrib()
    _tiere = attrib(factory=list)

    def __len__(self):
        return len(self._tiere)

    def __iter__(self):
        return iter(self._tiere)

    def add(self, tier):
        self._tiere.append(tier)

    def print(self):
        for tier in self:
            print(f"{tier.name} ({tier.art})")
        print(len(self))


@attrs
class Saeugetier(Tier):
    ART = "Säugetier"
    saeugerklasse = attrib()


@attrs
class Vogel(Tier):
    ART = "Vogel"
    ist_flugfaehig = attrib()
    schnabelfarbe = attrib()


@attrs
class Fisch(Tier):
    ART = "Fisch"
    lebensraum = attrib()
    fischart = attrib()


def main():
    affe = Saeugetier("Koko", "10.12.2014", 18874, "Pflanzentiere")
    fisch = Fisch("Nemo", "20.05.2010", 17896, "Süßwasser", "Raubfisch")
    vogel = Vogel("Sky", "02.12.2018", 147896, True, "blau")

    tierheim = Tierheim("AAAA")
    tierheim.add(affe)
    tierheim.add(fisch)
    tierheim.add(vogel)

    tierheim.print()
    
    print(tierheim)


if __name__ == "__main__":
    main()
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Benutzeravatar
__blackjack__
User
Beiträge: 14052
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@kusja: Nochmal zum Thema Aggregation/Komposition: In UML ist Komposition ein verstärkte Form von Aggregation.

Ein nettes, paxisrelevantes Ziat aus „The Elements of UML 2.0 Style“ von Scott W. Ambler:
145. Don’t Worry About the Diamonds
When you are deciding whether to use aggregation or composition over association, Craig Larman (2002) says it best: “If in doubt, leave it out.” The reality is that many modelers will agonize over when to use aggregation when the reality is that there is very little difference between association, aggregation, and composition at the coding level.
Ob zwischen Tierheim und Tier nun eine einfache Verbindung im UML-Diagramm besteht, oder da eine ausgefülltes oder nur umrandetes Karo am Tierheim-Ende der Beziehung steht, führt letztlich zum gleichen Code in Python. Das ist im Code einfach nicht wirklich unterscheidbar.

Ich bin mir auch nicht sicher was hier überhaupt die Aufgabe ist, denn im Betreff steht etwas von Vererbung und Komposition und in den Beiträgen stellst Du dann Aggregation und Komposition einander gegenüber. Welcher Unsinn soll denn da nun genau gemacht werden? Die offensichtliche Vererbung in eine Komposition prügeln oder die Aggregation (soll das ja laut Kommentaren beim Tierheim sein) in eine Komposition umwandeln? Letzteres ist total simpel: einfach den Kommentar ``# Aggregation`` in ``# Komposition`` ändern. ;-)
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Eine Sache die vielleicht erwähnenswert ist: Es gibt Sprachen die keine Vererbung erlauben. Da ist Komposition dann das Mittel der Wahl. Gemeinsamkeiten muss man dann anders ausdrücken z.B. über Interfaces, Traits oder Type Classes.

In Python gibt es dafür kein Sprachkonstrukt sondern nur Duck Typing, also reine Konvention. Hat den Nachteil dass es mit etwas Duplikation einhergeht. In dem Fall hättest du kein "Tier" mehr als etwas dass im Code explizit auftaucht.
Antworten