Klassen- und Objektdiagramme in UML?
Hallo Leute,
normalerweise hasse ich es, wenn man so lächerlich einfache Fragen, die sich mit zwei Minuten googeln selbst beantwortet, stellt, aber ich komme nach zwei Tagen Recherche immer noch nicht auf den Trichter:
Aufgabe:
Erstellen Sie ein UML-Diagramm für folgende, sowie eine weitere übergeordnete Klasse mit den gegebenen Attributen und Methoden. Geben Sie in ihrem UML-Diagramm auch Konstruktoren an. Passen Sie die Namen an, beachten Sie hierbei PEP 8.Erzeugen Sie eine sinnvolle Vererbungshierarchie zwischen den Klassen.
Hinweis: Überlegen Sie genau, was die angegebenen Klassen verbindet.
Angestellter
• Personalnummer
• Name
• Adresse
• Geburtsdatum
• Gehalt
• Bankverbindung
• DruckeAdresse()
• ÜberweiseGehalt()
Student
•Matrikelnummer
•Name
•Adresse
•Geburtsdatum
•DruckeAdresse()
•DruckeAusweis()
Hilfskraft
• Matrikelnummer
• Name
• Adresse
• Geburtsdatum
• Personalnummer
• Beschäftigungsart
• DruckeAdresse()
• DruckeAusweis()
• DruckeArbeitszeiten()
Erstellen Sie zwei Objektdiagramme, welche dieses Klassendiagramm erfüllen. Generieren Sie die erforderlichen Objektwerte
Mein Ansatz/Problem: Die eigenen Klassen interagieren doch überhaupt nicht miteinander? Die einzige Vererbung findet zwischen Stundeten und Hilfskraft statt. Selbst die Hilskraft bekommt noch nicht mal Gehalt. Wie soll man das in einem UML-Diagramm verbinden? Und soll man als Objektdiagramm dann einfach nur 8 Kästchen malen, ohne Pfeile?
3 Antworten
Hallo Jensek81,
Die einzige Vererbung findet zwischen Stundeten und Hilfskraft statt.
wie kommst Du darauf?
Alle gemeinsamen Methoden/Attribute kannst Du über Vererbung realisieren.
Name, Adresse, GeburtsDatum, DruckerAdresse
Steht ja extra noch da:
weitere übergeordnete Klasse
Die Klasse kannst Du "Person" nennen.
Gruß
ps: Man sollte der lehrenden Seite mal erzählen, dass Vererbung ziemlich "aus der Mode" ist und nur noch da benutzt wird, wo es absolut sinnvoll ist. Nicht so wie vor 10-15 Jahren, wo noch "alles mit Vererbung" gelöst wurde.
Gruß
Aber was solll die Student für Methoden ausführen? DruckeAdresse ist ja ein bisschen witzlos, weil er wird seine Adresse in der Regel wissen. DruckeAusweis() ist auch Quatsch, weil denn hat er ja in seiner Tasche. Gleiches gilt für den Angestellten. ÜberweiseGehalt(). Er soll sich selbst das Gehalt überweisen? Ich versteh nich, wie die Methoden ausgeführt werden sollen.
DruckeXYZ ist einfach nur schlecht gewählter Name, besser wäre nenneXYZ. (nennePersonalDaten, nenneDeineAdresse, usw.) Für eine Programmimplementation wird eine Konsolenausgabe reichen.
ÜberweiseGehalt könnte man auch eher empfangeGehalt nennen. Ausgeführt werden die Methoden später über das Objekt.
Angestellter irgendeinAngestellter = new Angestellter();
irgendeinAngestellter.empfangeGehalt();
Von der Logik her, da hast du Recht, sollte eher ein Drittobjekt Geld an den Angestellten überweisen:
int gehalt = irgendeinAngestellter.ermittleGehalt();
irgendeinAngestellter.empfangeGehalt(gehalt);
Danke für euere Antworten. Ich habe es jetzt so probiert (bild siehe unten):. Meine Frage: Muss ich jetzt überall noch set und get davor schreiben? Weil eigentlich müsste man als Angestellter z.B. auf seine Bankverbindung zu greifen können. Uns wurde aber gesagt, dass einige getter und setter deplaziert wären, weil bspw. kein Angestellter ernhaft ein Programm braucht um sein eigenes Geburtsdatum aufzurufen. Und welchen Datentyp haben bspw. DruckeAdresse () oder Geburtstag? Ist das ein "String" oder ein "void "?Danke für euere Antworten. Ich habe es jetzt so probiert. Meine Frage: Muss ich jetzt überall noch set und get davor schreiben? Weil eigentlich müsste man als Angestellter z.B. auf seine Bankverbindung zu greifen können. Uns wurde aber gesagt, dass einige getter und setter deplaziert wären, weil bspw. kein Angestellter ernhaft ein Programm braucht um sein eigenes Geburtsdatum aufzurufen. Und welchen Datentyp haben bspw. DruckeAdresse () oder Geburtstag? Ist das ein "String" oder ein "void "?
druckeAdresse() hat den Rückgabetyp void und gibt einfach nur die Adresse auf der Konsole aus.
Was get und set angeht hat ja regex9 schon etwas dazu geschrieben. Es gibt da allerdings verschiedene Auffassungen. Richtung Prüfung würde ich mich vorher erkundigen ob getter und setter weggelassen werden können - Du willst nicht nach der Prüfung feststellen, dass dich jede fehlende Methode einen Punkt gekostet hat.
weil bspw. kein Angestellter ernhaft ein Programm braucht um sein eigenes Geburtsdatum aufzurufen
Ich habe das Gefühl, dass deine Denkweise noch nicht ganz zur Aufgabenstellung passt. Du sollst die vorgegebenen Personen, bzw. Eigenschaften dieser Personen, modellieren. Es geht nicht darum, dass ein Angestellter kein Programm braucht um sein Geburtsdatum auszugeben. Es ist gefordert, dass Du zu Personen das Geburtsdatum ausgeben können sollst. Stell dir vor Du sollst ein Programm Entwickeln um Personen rund um die Uni zu verwalten.
Du hast dort keine "echten Personen", du hast ein Datenmodell mit dem Du arbeiten kannst. Du könntest zum Beispiel die Aufgabe lösen "gib alle Personen älter als X aus".
Den Objekten ist völlig "egal" was sie tun und was sie genau abbilden. Du, bzw. die Aufgabenstellung, entscheiden.
Gruß
Aber "Angesteller" erbt doch nicht alles von "Hilfskraft". Der Angestellte bekommt ja Gehalt, die Hilfskraft nicht. Also kann das nicht über die Vererbung realisiert werden, oder?
Ich weiß nicht wie Du auf die Idee kommst, dass Angestellter von Hilfskraft erbt.
Lass doch Hilfskraft von Student erben. Angestellter hat doch nur ein paar Attribute mehr als ein Student, das passt doch sehr gut.
Gruß
- ersichtlich haben die Klassen die Attribute „Name“/„Adresse“/„Geburtsdatum“ und di Methode „DruckeAdresse“ gemeinsam... man braucht also ne Klasse wie „Person“ oder so...
- die Hilfskraft ist offenbar auch Student...
- man könnte jetzt überlegen, ob man wegen „Personalnummer“ ne Klasse „Arbeitnehmer“ macht... LOL
- der Rest ist eben individuell...
Danke für die Antwort.
Was soll denn der Angestellte für Methoden durchführen? DruckeAdresse()? Seine eigene Adresse muss er ja nicht ausdrucken? ÜberweiseGehalt()...er kann sich ja schlecht sein Gehalt selbst überweisen? Er führt also keine Methode durch?
- die Person muss ihre Adresse drucken können... das vererbt sich dann...
- warum soll man seine eigene Adresse nich drucken können müssen? ich würd sogar sagen: das ist die einzige Adresse die er drucken darf... und drucken können muss...
- naja... die Methode ÜberweiseGehalt() ruft ja der Arbeitgeber auf... es ist ja nicht der Angestellte, der da im Computer hockt, sondern es ist nur eine Abbildung der Merkmale und Arbeitsabläufe, die mit dem Angestellten verknüpft sind...
Danke für euere Antworten. Ich habe es jetzt so probiert. Meine Frage: Muss ich jetzt überall noch set und get davor schreiben? Weil eigentlich müsste man als Angestellter z.B. auf seine Bankverbindung zu greifen können. Uns wurde aber gesagt, dass einige getter und setter deplaziert wären, weil bspw. kein Angestellter ernhaft ein Programm braucht um sein eigenes Geburtsdatum aufzurufen. Und welchen Datentyp haben bspw. DruckeAdresse () oder Geburtstag? Ist das ein "String" oder ein "void "?

Setter / Getter-Methoden werden in einem UML-Diagramm grundsätzlich ausgeschlossen, denn sie sind trivial. Sie würden das Diagramm eh nur aufblähen. Konkret solltest du sie jedoch implementieren, sofern sie denn benötigt werden.
(...) weil bspw. kein Angestellter ernhaft ein Programm braucht um sein eigenes Geburtsdatum aufzurufen.
Ist denn definiert, was das Programm, bis auf die Abbildung verschiedener Objekte, machen soll? Es könnte ja dazu verwendet werden, mehrere Personen / Angestellte / Studenten, etc. anzulegen und zu verwalten.
Solltet ihr mit Python arbeiten, überspringe die folgenden beiden Miniabsätze.
Wenn man ein Objekt Person erstellt, möchte man sicherlich auch Geburtsdatum, etc. setzen. Da ein Standardkonstruktor vorgeschrieben ist, gibt es nur die Möglichkeit, direkt auf die Attribute zuzugreifen (was gegen das Prinzip der Kapselung verstößt) oder Setter-Methoden zu nutzen.
Das Gleiche gilt für die Ausgabe von Daten.
Und welchen Datentyp haben bspw. DruckeAdresse () oder Geburtstag?
Ersteres ist eine Methode. Wie ich hier schon schrieb, der Name ist nicht unbedingt günstig, soll aber wohl darauf hindeuten, dass eine Konsolenausgabe gemeint ist. Anhand des Bezeichners kannst du den Rückgabetyp herauslesen. Wenn jemand zu dir sagt: Kopiere das für mich, drucke dies für mich, schreibe das für mich, o.ä. ..., dann tust du das nur. Ein Unterschied wäre es zu einer Formulierung wie hole mir, gib mir.
Letzteres sollte günstigerweise ein Datum sein. Wenn du weißt, mit welcher Programmiersprache die Anwendung später entwickelt werden soll, kannst du den spezifischen Typnamen heraussuchen. Ansonsten reicht es auch, einfach nur den Typnamen zu definieren, der vom Namen passen würde (Date).
Zu deinem Diagramm:
- Die Pfeile musst du auf jeden Fall noch richtig setzen. Unabhängig von der Logik dürften sie nicht unterbrochen sein.
- Eine Vererbung sieht in UML anders aus, der Pfeil ist falsch. Siehe hier.
- Soll _init_ den Konstruktor darstellen? Dieser wird üblicherweise in die Sektion der Methoden (und nach oben sortiert) geschrieben, sofern er den Standardkonstruktor überlädt.
- Orientierst du dich an Python? Der snake_stil und der Name des Konstruktors weisen etwas daraufhin. Doch wird der Konstruktor in Python eigentlich mit zwei Unterstrichen umklammert: __init__. Ich würde den Konstruktor so schreiben: Person() - wenn man von meinem vorherigen Punkt einmal absieht.
- Es fehlen Angaben zur Sichtbarkeit der Attribute und Methoden. Wenn ihr mit Python arbeitet, kannst du dies ignorieren. Halte dich in dem Fall jedoch an Python-Konventionen (lies hier).
Ich denke mal, es geht vorrangig nur darum, es zu üben - egal, wie oft es in der Praxis eingesetzt wird. In meiner damaligen Studienzeit wurde schon auf die Vorlesungsfolie gedruckt, dass Anfänger dazu neigen, viel Vererbung einzusetzen, obwohl es gar nicht notwendig ist.