Zwölfhundertvierundsechzig

Als Programmierschlampe gehört es zu meinem Job, objektorientiert zu denken.
Da ich ohnehin gelegentlich ein paar Konzepte der Softwareentwicklung vorstellen wollte, geht es heute um Objekte.

Da stellen wir uns mal ganz dumm, und fragen: Was ist das – ein Objekt?
Da ich nicht zu tief in die informatische Theorie eindringen will (und kann), zeige ich es anhand eines anschaulichen Beispieles auf.

Nehmen wir das Beispiel „Person“.
Eine Person hat verschiedene Eigenschaften, wie Vorname, Nachname, Geburtsdatum, Geschlecht, Augenfarbe, etc., die sich für gewöhnlich nicht ändern.
Wenn ich also beispielsweise den Vornamen einer Person erfahren will, kann ich ihn auslesen durch aPerson.Firstname. Dabei ist aPerson eine Instanz des Objektes Person.
Andere Eigenschaften, z.B. die Adresse oder die Haarlänge können sich dagegen ändern. Diese Art Eigenschaft ist also nicht konstant.

Wenn ich jetzt etwa das Alter einer Person erfahren will, kann ich eine Methode aufrufen. aPerson.Age() gibt das Alter dieser Person zurück, indem das Geburtsdatum dieser Person (das ja in der Objektinstanz gespeichert ist) vom aktuellen Datum abgezogen wird (und ein paar Konvertierungsroutinen, die uns hier aber nicht interessieren).
Eine Objektinstanz kann alle möglichen Methoden ausführen: mit aPerson.Eat() isst sie, aPerson.Sing(aSong) lässt sie das Lied aSong singen, und durch aPerson.Sleep(aTime) schläft aPerson für die Zeitdauer aTime, um nur eine wenige Beispiele zu nennen. Oder bei aPerson.Hug(bPerson) umarmt aPerson eine andere Person bPerson.
Als weiteres Beispiel könnte eine Boole’sche Methode .IsTooFat() implementiert sein als .Weight() > BMI_MAX_ACCEPTABLE * .Height * .Height.

Auch die oben genannte Eigenschaft Adresse würde man üblicherweise über einen Getter aPerson.GetAddress() abfragen.
Umgekehrt gibt es auch Setter, mit denen sich die Eigenschaften einer Person ändern lassen (sofern nicht read-only).
Der Clou an Getter und Setter ist, dass man außer der Abfrage oder Zuweisung auch noch anderen Code ausführen kann (z.B. andere Statusvariablen aktualisieren, oder was der Entwickler sonst für sinnvoll erachtet).

Es geht zwar etwas zu weit, aber der Vollständigkeit halber muss ich es doch erwähnen. Jede Objektinstanz muss erzeugt werden, um u.a. Speicherplatz zu alloziieren und Initialisierungen zu machen. Erst dann kann man darauf zugreifen. Ansonsten gäbe es eine Zugriffsverletzung. Zum Erzeugen benötigt man den sog. Konstruktor, der eine spezielle Methode ist, die einen Pointer auf die Speicheradresse der Objektinstanz zurückgibt.
Nachdem man das Objekt nicht mehr braucht, gibt man es wieder durch Aufruf des Destruktors frei, um Speicherleaks zu vermeiden und sonstige Finalisierungen auszuführen (es sei denn, der Garbage Collector kümmert sich darum, dem trau‘ ich aber nicht so recht). Nach dem Freigabe ist es sinnvoll, das Objekt auf Null zu setzen. Denn dies lässt sich leicht abprüfen, und vermeidet, dass man versehentlich in die Datenpampas zugreift.

Nun gibt es ja verschiedene Arten von Personen.
Die allermeisten von ihnen lassen sich problemlos in männlich und weiblich aufteilen.
Also spezifizieren zwei neue Objektklassen Male und Female (und meinetwegen auch noch Other). Beide Objektklassen erben vom Objekt Person die meisten Eigenschaften. Jede Person hat ein z.B. Geburtsdatum. Also hat auch jede Male- oder Female-Instanz ein Geburtsdatum.
Der Vorteil unterschiedlicher Objektklassen ist, dass diese zusätzlich zu den Eigenschaften und Methoden der Basisklasse noch andere Eigenschaften und Methoden haben können. Auch können sie bei gleichem Methodenaufruf unterschiedlichen Code ausführen, ohne dass der Programmierer das jedesmal extra abfragen muss.
Eine Boole’sche Methode aPerson.HasPenis() etwa liefert bei einer Male-Instanz TRUE, und einer Female-Instanz FALSE zurück. (Bei Other wird eine Exception ausgelöst, da der Rückgabewert nicht definiert wäre.)
Diese Art der Vererbung ist ein essenzielles Konzept der Objektorientierten Programmierung, da es die Wartung der Sourcen wesentlich vereinfacht, denn viel Code muss nur einmal implementiert werden, und kann dann für andere Objektklassen wiederverwendet werden.

Ein besonderer Objektpointer ist die this-Variable. Mit this kann sich ein Objekt selbst referenzieren. Dies ist manchmal nötig. Während etwa .Touch(HAIR, bPerson) das Objekt anweist, die Haare von bPerson zu berühren, berührt .Touch(HAIR, this) die eigenen Haare (ein noch blöderes Beispiel habe ich nicht gefunden).

Noch interessanter wird es, wenn mehrere Objekte miteinander verknüpft sind.
Jede Person hat zwei Eltern. Mit aPerson.Father und aPerson.Mother kann man die jeweiligen Werte als Eigenschaften der Objektinstanz aPerson auslesen.

Ich glaube, das reicht für diesen Eintrag. Das wesentliche habe ich, denke ich genannt. Wer nie mit OOP zu tun hat, braucht noch nicht einmal das, und wer doch, weiß das eh alles (und vermutlich noch mehr).

Über Anne Nühm (breakpoint)

Die Programmierschlampe.
Dieser Beitrag wurde unter Uncategorized abgelegt und mit , verschlagwortet. Setze ein Lesezeichen auf den Permalink.

24 Antworten zu Zwölfhundertvierundsechzig

  1. Mein Name sei MAMA schreibt:

    Public Blog1264
    do {
    aPerson.Read(Blog1264)
    } until aPerson.LOL();
    oder so ähnlich
    🙂

    Like

  2. Plietsche Jung schreibt:

    Die Worte Destruktors und Speicherleaks gefallen mir besonders !
    Es lebe Turbo-Pascal !

    Like

  3. UH schreibt:

    Interessanter Blog, lese ihn nun schon eine Weile,gefällt mir – weiter so. :-h

    Ich kann mich über den Garbage Colletor nicht beschweren, der macht immer was er soll bei mir *-:-)

    Wie wäre es übrigens mit der Erklärung der Abstraktion, fehlte mir, obwohl schon fast im Text mit beschrieben.

    Like

    • Dankeschön für das Feedback. 🙂

      Beim Aufruf des Destruktors geht es oft nicht nur darum, Speicher freizugeben, sondern es muss manchmal auch noch anderer Code ausgeführt werden.
      Deshalb habe ich es mir grundsätzlich angewöhnt, den Destruktor aufzurufen, auch wenn das nicht unbedingt nötig wäre.

      Ich versuch’s mal mit der Abstraktion:
      Wenn eine Methode bei einer Basisklasse als „abstact“ deklariert wird, wird diese Methode nicht dort implementiert, sondern bei den abgeleiteten Klassen.

      Like

  4. ednong schreibt:

    „… (und vermutlich noch mehr)“ – oh ja. Aber schön beschrieben.

    Like

    • (Wo ist meine Antwort abgeblieben? Hatte vorhin doch schon abgeschickt. Also nochmal – so ungefähr)

      Ursprünglich wollte ich als Beispiel geometrische Figuren wie Rechtecke oder Ellipsen (über Vektorgrafik hatte ich schon irgendwo gebloggt) nehmen, die sich selbst auf eine Zeichenfläche zeichnen.
      Aber Personen erschienen mir dann anschaulicher. Ähnliche Objekte braucht man etwa bei Genealogieprogrammen oder etlichen Computerspielen.

      Like

  5. UH schreibt:

    Destruktor nutze ich nur sehr selten, weil meiner bisherigen Erfahrung nach es fast auch ohne geht. Aber darüber kann man sich vortrefflich streiten, je nach Sprache.

    Das hätte man doch am Beispiel von Person besser erklärt, finde ich. Z. B. mit verteilen der Eigenschaften auf AbstraktePerson und IndividuellePerson. 😉

    Like

    • Hm .. nehmen wir an, o.g. Methode .Eat() sei abstrakt.
      Eine Klasse Vegetarier, die von der Klasse Person erbt, würde beim Aufruf von .Eat() erst abprüfen, ob Fleisch oder Fisch dabei ist, und dieses ablehnen.
      Oder eine Klasse Allergiker ..
      Das Beispiel ist nicht besonders gut, aber man sieht vielleicht, worauf es hinausläuft.

      Like

  6. raid schreibt:

    Mit Java scheinst du schonmal nicht zu programmieren 😅

    Mich würde in dem Zusammenhang mal interessieren, was du von matlab (bzw octave etc) hältst. Von C(++) kommend erstmal sehr ungewöhnlich, dass alles ohne Definition des Datentyps irgendwie gespeichert wird..

    Like

    • Nee, Java mag ich nicht. Ist langsam, und es gibt häufig Versionswirrwarr.

      Mit Matlab (oder Mathematica, Mathcad) habe ich nicht viel gemacht. Carsten spielt gelegentlich damit herum, wenn er mal etwas Zeit hat.
      Ich bin an stark typisierte Sprachen gewöhnt, und hatte bereits mit PHP gelegentlich Probleme, weil die Typbehandlung nur Wischiwaschi ist.

      Like

    • Engywuck schreibt:

      bei Java muss ich immer an „verteiltes Echtzeit-Java“ denken. Wobei ich das immer für eine Satire gehalten habe, aber es scheint echt einen Spezification Request dafür zu geben… (JSR 50, seit Anno 2000)

      Like

  7. aliasnimue schreibt:

    Bei einer Fortbildung hatte ich mal ein paar Wochen PHP. Der Dozent war gerade mal Mitte 20 und ein echter Nerd. (Pizza/Cola) Die Begeisterung ist aber auf niemanden übergesprungen.

    Like

  8. Pingback: Tweeeeets //1466 | breakpoint

  9. Pingback: Am Anfang war das Bit – #Blogparade zur Digitalisierung @OttoGroup_Com //1482 | breakpoint

  10. Pingback: Der fensterlnde Nachrichtendienst //1533 | breakpoint

  11. Pingback: Kurz notiert – KW 15/2018 | ☨auschfrei

  12. Pingback: Partygäste //1954 | breakpoint

  13. Pingback: breakplaining: Pointer //1971 | breakpoint

Hinterlasse einen Kommentar