1 / 60

Gliederung

Gliederung. Komplexe(re)s Beispiel: Steuer v.Beschäftigte(n) Aspekte des Software Engineering (Anforderungsanalyse) SW- Entwurf --> Klassifikationshierarchie Implementierung --> Klassenhierarchie Implementierungsaspekte Klassenhierarchie - virtual/rein virtual

Download Presentation

Gliederung

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Gliederung • Komplexe(re)s Beispiel: Steuer v.Beschäftigte(n) • Aspekte des Software Engineering • (Anforderungsanalyse) • SW- Entwurf --> Klassifikationshierarchie • Implementierung --> Klassenhierarchie • Implementierungsaspekte • Klassenhierarchie - virtual/rein virtual • inline - Wiederholung Liste - rand() • (Vorteil des OO-Ansatzes) • Erweiterung • Nachteil von alternativem Ansatz

  2. Beschäftigte • Grobklassifikation: • Angestellte: festbesoldet • Arbeiter: Entlohnung nach Arbeitsstunden • Steuern: • Freibetrag: (abhängig von Position) • Einheitlicher Steuersatz: 45%

  3. Beschäftigte (Forts.) • also: • Steuer = ((Gehalt - Freibetrag)*45)/100, • Freibetrag ergibt sich aus Basisfreibetrag + Zusatzfreibetrag, • Basisfreibetrag für alle: 500 DM

  4. Beschäftigte (Forts.) • Angestellte: • B1: 4000 DM, Zusatzfreibetrag: 200 DM, • B2: 6000 DM, Zusatzfreibetrag: 400 DM. • Arbeiter: • A1: Stundenlohn: 20 DM • A2: Stundenlohn: 30 DM • Zusatzfreibetrag für alle: 100 DM.

  5. Klassifikationshierarchie

  6. Aufgabe • Realisierung dieser Hierarchie • Implementierung auf Grundlage der Modellierung --> einige neue Gesichtspunkte und Ideen. • Berechnungen: • Gehaltssumme • Summe anderer Ausgaben. • Erweiterung der Hierarchie • um B3

  7. Programm-Entwurf • Klassifikationshierarchie angemessen berücksichtigen: • Vererbung folgt der (Modellierungs-)Hierarchie • In der Hierarchie angegebene Attribute etc. an der richtigen Stelle darstellen • Attribute und Methoden "so hoch wie mög- lich im Baum" anbringen.

  8. Konsequenzen • Jedem Knoten im Kassifikationsbaum entspricht eine Klasse. • Die Relation IstSohnVon in der Klassifikationshierarchie wird übersetzt in ErbtVon in der Klassenhierarchie.

  9. Programm-Entwurf (Forts.) • Abstrakte Methoden da, wo • der Name bereits bekannt sein sollte, • der Name schon verwendet werden kann, • der Code noch nicht angegeben werden kann oder soll.

  10. wichtige Kategorie auch in der Softwaretechnik Programm-Entwurf (Forts.) • Zugriffsspezifikationen angemessen berücksichtigen: • Sie werden in der (Modell-)Hierarchie nicht dargestellt. • Hier hilft gesunder Menschenverstand.

  11. rein virtuelle Funktionen Die Klasse Beschaeftigter als Wurzel class Beschaeftigter { private: char * Name; protected: static const int BasisFreibetrag = 500;//* virtual int DerZusatzfreibetrag() = 0; public: Beschaeftigter(char *); virtual int Gehalt() = 0; int Freibetrag(); int Steuer(); char * DerName(); virtual void Druck (); }; * In Borland so nicht: "Mag der Compiler nicht". Konstante

  12. Konstruktor/ Druck Beschaeftigter :: Beschaeftigter(char * t) { Name = new char[strlen(t)]; strcpy(Name, t); } void Beschaeftigter::Druck() { cout << "Name: "<< DerName() << "\t\tGehalt: "<< Gehalt() << endl; }

  13. Berechnung der Steuer • Bemerkenswert: • Gehalt ist rein virtuell • der Code ist also an dieser Stelle nicht bekannt, • er wird erst später klassenspezifisch nachgetragen. • Steuern sollten (numerisch) positiv sein!

  14. Beachten Sie: rein virtuelle Methoden Weitere Methoden • Ausgabe des Namens • Berechnung des Freibetrags • Berechnung der Steuer char * Beschaeftigter::DerName() { return Name;} int Beschaeftigter ::Freibetrag() { return BasisFreibetrag + DerZusatzfreibetrag();} int Beschaeftigter::Steuer() { int SteuerGehalt = Gehalt() - Freibetrag(); return (SteuerGehalt > 0 ? (SteuerGehalt*45)/100 : 0) ;}

  15. Nächste Ebene • Implementiert werden sollten • die Klasse Angestellter, • die Klasse Arbeiter. • Angestellter: keine besonderen Angaben • Arbeiter: schon komplizierter.

  16. Die Klasse der Angestellten class Angestellter : public Beschaeftigter { protected: int FestGehalt; public: Angestellter(char * t): Beschaeftigter (t) {} }; Konstruktor wird mit dem Code angegeben, der ihn implementiert (inline-Formulierung)

  17. Einschub zu : inline • Zum Abarbeiten einer Methode: • Konstruktion eines activation record mit • Werten der aktuellen Parameter, • Werten lokaler Variablen, • Rückgabewert, Rücksprungadresse etc. • Beim Aufruf der Methode: • Aktivierung des activation record auf dem Laufzeitstack • Rücksprung an die Stelle des Aufrufs, wenn der Aufruf abgearbeitet ist.

  18. Einschub: inline (Forts.) • Methodenaufruf zeitintensiv • -> bei einfachen Methoden: Verwaltungsaufwand höher als der Aufwand für die Berechnung. • Alternative: inline • Spare mir den Aufwand mit dem activation record, • kopiere dafür den Code für die Methode direkt an die Stelle im Aufruf.

  19. Einschub: inline (Forts.) • •inline-Formulierung sollte (nur) in einfachen Fällen benutzt werden: Vereinfacht die Formulierung erheblich, wird also hier i.f. (stillschweigend) verwendet. • • Ist Frage der Implementierung Ändert also nicht die Wirkung (Semantik) der Funktion.

  20. Angestellter B1 • • Stellen keine abstrakte Klasse dar: • Es sollen Objekte dieses Typs erzeugt werden, • alle Angaben sind vorhanden. • • Konsequenz: • Die rein virtuellen Methoden, die noch nicht implementiert wurden, müssen in dieser Klasse realisiert werden: • Gehalt • DerZusatzfreibetrag

  21. Klassendefinition class AngestellterB1 : public Angestellter { public: AngestellterB1(char * t): Angestellter(t) {FestGehalt = 4000;} int Gehalt() {return FestGehalt;} int DerZusatzfreibetrag() {return 200;} void Druck () { cout<< " Angestellter B1\t" ; Beschaeftigter::Druck(); }; };

  22. Die Klasse Arbeiter • Rein virtuelle Methoden • DerZusatzfreibetrag, Gehalt • hier implementierbar. • Dazu Einführung einer rein virtuellen Methode DerStundenlohn • gibt den Stundenlohn für die jeweilige Klasse an • verwendbar, ohne daß der Wert dafür bekannt.

  23. Die Klasse Arbeiter (Forts.) class Arbeiter: public Beschaeftigter { protected: int StundenZahl; int DerZusatzfreibetrag() {return 100;} public: Arbeiter(char * t):Beschaeftigter(t) {} void SetzeStunden(int v) {StundenZahl = v;} int DieStundenZahl() {return StundenZahl;} virtual int DerStundenlohn() = 0; int Gehalt() { return DerStundenlohn()*DieStundenZahl();} };

  24. ArbeiterA1 • Die Klasse ist nicht abstrakt. • Vorgehen wie oben für AngestellterB1: • muß die bislang virtuell gebliebenen Methoden definieren

  25. ArbeiterA1 (Forts.) class ArbeiterA1: public Arbeiter { public: ArbeiterA1(char *, int); int DerStundenlohn() { return 20; } void Druck () { cout<< " Arbeiter A1\t\t" ; Beschaeftigter::Druck(); }; }; ArbeiterA1:: ArbeiterA1(char * t, int w): Arbeiter(t) { StundenZahl = w; }

  26. Andere Klassen • Definition der anderen Klassen: • AngestellterB2 • ArbeiterA2 völlig analog zu den angegebenen Definitionen, wird daher hier nicht wiederholt.

  27. Zusammenfassung • Konstruktion einer Klassifikationshierarchie aus einer Beschreibung • Daten • Verhalten, d.h. Methoden • Umsetzung in eine Klassenhierarchie • Überlegung, wo Komponenten (Methoden, Attribute) angebracht werden,

  28. Zusammenfassung (Forts.) • Analyse, an welcher Stelle welche Methode benötigt wird, • Überlegung, an welcher Stelle welche Methode definiert werden kann • d.h.auch: Realisierung abstrakter Klassen/ [rein] virtueller Methoden. • Technisch: • Einführung von inline-Code.

  29. Buchhalteraufgabe • Aufgabe: • Bestimme, was monatlich an Gehältern, Steuern und Freibeträgen zusammenkommt. • Lösungsplan: • Verwalte die Beschäftigten • z.B. in einer verketteten Liste • Iteriere über die Liste und ermittle die benötigten Daten.

  30. Nutzinfo weiter Zur Konstruktion der Liste • Listenelement: • Attribute: • weiter: Zeiger auf Listenelement Nutzinfo (hier: (Zeiger auf) Beschaeftigter) • Methoden: Holen, Setzen der Nutzinfos Beschäftigter

  31. Zur Konstruktion der Liste • class BeschaeftigtenListenEl { • private: • Beschaeftigter * Nutzinfo; • public: • BeschaeftigtenListenEl * weiter; • Beschaeftigter * Get_Beschaeftigten(); • void Set_Beschaeftigten(Beschaeftigter *);}; • Beschaeftigter * • BeschaeftigtenListenEl::Get_Beschaeftigten(){ • return Nutzinfo;}; • void BeschaeftigtenListenEl:: • Set_Beschaeftigten(Beschaeftigter * wen){ • Nutzinfo=wen;};

  32. Zur Konstruktion der Liste • Zur Liste selbst: • Attribute: • Kopf, Aktuelles Element • Methoden: • Konstruktor • Einfügen in Liste (d.h. Engagieren eines Beschaeftigten), Starten der Iteration Inspektion des aktuellen Elements Weiterschalten (möglich?)/Am Ende der L.

  33. Zur Konstruktion der Liste • class BeschaeftigtenListe { • public: • BeschaeftigtenListenEl * Kopf; • BeschaeftigtenListenEl * • AktuellesElement; • BeschaeftigtenListe(); • void Engagieren(Beschaeftigter *); • void StartIteration(); • Beschaeftigter * • DieserBeschaeftigte(); • int WeiterSchalten(); • };

  34. Zu den Methoden • Konstruktor: • BeschaeftigtenListe::BeschaeftigtenListe() { • Kopf = NULL; • AktuellesElement = NULL;} • Einfügen: • void BeschaeftigtenListe:: Engagieren(Beschaeftigter * wen) { • BeschaeftigtenListenEl * • HilfsKopf = new BeschaeftigtenListenEl; • HilfsKopf->Set_Beschaeftigten(wen); • HilfsKopf->weiter = Kopf; Kopf = HilfsKopf;}

  35. Zu den Methoden • Startiteration: • void BeschaeftigtenListe::StartIteration() { AktuellesElement = Kopf;} • Inspektion des aktuellen Elements : • Beschaeftigter * BeschaeftigtenListe:: • DieserBeschaeftigte() { • if (AktuellesElement == NULL) • return NULL; • else return • AktuellesElement->Get_Beschaeftigten();}

  36. Zu den Methoden • Weiterschalten (+ Am Ende der Liste ?) Es muß klar sein, wann die Liste zu Ende durchlaufen ist. Gib dann -1 aus, und sonst 0; also: • int BeschaeftigtenListe::WeiterSchalten() { • if (AktuellesElement->weiter == NULL) • return -1; • else { • AktuellesElement = • AktuellesElement->weiter; • return 0;}

  37. Zur Entstehung der Liste • Durch Zufallszahlen: • Erzeuge eine ganzzahlige Zufallszahl • über Funktion rand() aus „stdlib.h“ • Abhängig vom Rest der Division durch 4 wird ein entsprechender Beschäftigter erzeugt. • Analog: Erzeuge zufällig Namen. • Baue damit Liste mit (hier:) 15 Einträgen auf.

  38. Code 1 • BeschaeftigtenListe * • Mitarbeiterliste = new BeschaeftigtenListe; • // Erzeugen der Listeneinträge • int zufall=rand(); • char * nme = new char [6]; • nme[5] = '\0'; • cout << "Beschäftigte und • deren Gehälter: "<< endl;

  39. Code 2 • for (int j = 0; j < 15; j++) • { for ( int i = 0;i < 5; i++) • { • nme[i] = (rand()%26)+65; • // Zufallszahlen zwischen 65-91 bestimmen; • entsprechen A-Z • } • int A1_Stunden = zufall%168; • int A2_Stunden = zufall%200; • Beschaeftigter * einBeschaeftigter; • int switsch = zufall % 4;

  40. Code 3 • switch (switsch){ • case 0: einBeschaeftigter • = new AngestellterB1(nme);break; • case 1: • einBeschaeftigter • = new AngestellterB2(nme);break; • case 2: • einBeschaeftigter • = new ArbeiterA1(nme, A1_Stunden);break; • case 3: • einBeschaeftigter • = new ArbeiterA2(nme, A2_Stunden);break;}

  41. Code 4 • Mitarbeiterliste • ->Engagieren(einBeschaeftigter); • einBeschaeftigter->Druck(); • zufall = rand(); • } • cout << endl;

  42. Verwendung der Liste • Akkumulierte Werte berechnen • Akkumulierte Werte ausgeben

  43. Code 1 • // Akkumulierte Werte berechnen: • Mitarbeiterliste->StartIteration(); • Beschaeftigter * akt_Beschaeftigter = Mitarbeiterliste->DieserBeschaeftigte(); • long int gehaltsSumme = • akt_Beschaeftigter->Gehalt(); • long int steuerSumme = • akt_Beschaeftigter->Steuer(); • long int freiBetragsSumme = akt_Beschaeftigter->Freibetrag();

  44. Code 2 • // Akkumulierte Werte berechnen 2: • while (Mitarbeiterliste->WeiterSchalten() == 0) { • akt_Beschaeftigter = • Mitarbeiterliste->DieserBeschaeftigte(); • gehaltsSumme += • akt_Beschaeftigter->Gehalt(); • steuerSumme += • akt_Beschaeftigter->Steuer(); • freiBetragsSumme += • akt_Beschaeftigter->Freibetrag(); • }

  45. Code 3 • // Akkumulierte Werte ausgeben: • cout <<"Insgesamt also (alle Beträge in DM): " • << endl • << "Gehälter:\t\t" << gehaltsSumme • << endl • << "Steuern:\t\t" << steuerSumme • << endl • << "Freibeträge:\t" << freiBetragsSumme • << endl; Steuern 1 Prog Steuern 1 Quelltext

  46. Ausgabe auf Console • Beschäftigte und deren Gehälter: • Arbeiter A1 Name: MZRHL Gehalt: 760 • Arbeiter A1 Name: JOETB Gehalt: 3240 • Angestellter B1 Name: WLTZT Gehalt: 4000 • Angestellter B2 Name: IEMHP Gehalt: 6000 • Arbeiter A2 Name: YBPSW Gehalt: 5010 • Angestellter B1 Name: JCCVJ Gehalt: 4000 • Arbeiter A1 Name: FJEEE Gehalt: 3080 • Angestellter B2 Name: JZYLN Gehalt: 6000 • Arbeiter A1 Name: EXKSZ Gehalt: 520 • Arbeiter A1 Name: ASXFV Gehalt: 1320

  47. Ausgabe auf Console 2 • Beschäftigte und deren Gehälter (Fortsetzung): • Arbeiter A2 Name: FFUCR Gehalt: 2370 • Angestellter B1 Name: JDUGC Gehalt: 4000 • Arbeiter A1 Name: KKKIX Gehalt: 2920 • Angestellter B2 Name: ETOBW Gehalt: 6000 • Angestellter B1 Name: VDFQJ Gehalt: 4000 • Insgesamt also (alle Beträge in DM): • Gehälter: 53220 • Steuern: 19349 • Freibeträge: 10300

  48. Zu beachten • Formulierung nimmt keinen Bezug auf den Typ des Beschäftigten. • Flexibilität durch objektorientierten Zugang • Vererbung • dynamisches Binden • Änderungsfreundlichkeit durch Objektorien-tierung.

  49. AngestellterB3 • • Ist Angestellter • Festgehalt: 8000 DM, Zusatzfreibetrag: 1000 DM • • Berücksichtigung in der Hierarchie: • Einfügen der entsprechenden Klasse. • • Darstellung der Klasse • mit minimalem Aufwand durch Vererbung.

More Related