Programmieren - alles kontrollieren 4.939 Themen, 20.672 Beiträge

Objektorientiert denken....aber wie? (in delphi7)

KoRny Boy / 3 Antworten / Flachansicht Nickles

moin programmierer

ich bin schon seit längerem von pascal nach delphi umgestiegen....

ich häng immernoch an der strukturierten denkweise und komm davon nich weg...immer wenn ich versuch irgendwas objektorientiert zu programmieren, fall ich zurück auf die strukturierte programmierung....kp...krieg ich irgendwie nich gebacken....

kann mir irgendwer versuchen zu erklären wie man OOP macht, bzw umdenken kann...möglichst in delphi....vllt auch mit nem beispiel...so quasi einmal die ausführung in der strukturierten programmierung und einmal in der oop...

danke schon mal für jede hilfe

mfg KoRny Boy

Wer anderen eine Grube gräbt ist selbst ein Schwein
bei Antwort benachrichtigen
Andreas42 KoRny Boy „Objektorientiert denken....aber wie? (in delphi7)“
Optionen

Hi!

Dieses Umstellen in der "Denke" bei der Programmentwicklung musst du leider selbst schaffen, da kann man nicht wirklich hingeführt werden - ist jedenfalls meine Überzeugung. natürlich kann ich dir aber versuchen Tipps zu geben. ;-)

Eine Warnung vorweg (auch an alle "linientreuen" Gurus): ich hab' mir das selbst beigebracht und folge da nicht immer der reinen Lehre... Kritik ist daher auch bei mir immer willkommen. :)


OK, fangen wir an:

Mich hat das Gerede, dass im Objektorienten alles anders ist, zuerst auch abgeschreckt. Die Beispiele waren damals auch nicht wirklich hilfreich. Ich hab' den Umstieg dann unter Turbopascal gemacht, dass ja ab Version 5.5 eine erste Implementierung in diese Richtung mitbrachte.

Wenn man sich einen RECORD und eine OBJECT/CLASS-Definition ansieht, dann fällt einem auf, dass man das Wort "RECORD" durch "OBJECT" ersetzen kann, der Compiler schluckt das. naja, Objektdefinitionen sind also eigentlich nicht wirklich etwas komplett anderes.
Das sollte einen nicht zu stark wundern: die ganze EDV-Geschichte lebt von Evolution, nicht von Revolution. ;-)


Weiterentwicklung:

Eigentlich erreicht jeder einen gewissen Punkt in seiner eigenen "Programmentwicklung": man erzeugt datenstrukturen (RECORD, SET oder STRUC), die dann von bestimmtion Funktionen bearbeitet werden. Richtig unabhängig sind diese beiden Bestandteile (Datenstrukturen und Bearbeitungsfunktionen) in der Praxis eigentlich nie, es gibt aber keine formelle Verbindung.

Es liegt also eigentlich nahe eine Programmstruktur zu schaffen, die datentypen und bearbeitende Funktionen zusammenfasst.

Ich hätte dabei an eine Fabrik gedacht, die Lager und Produktion in einem Gebäude zusammenfasst und diesen datentyp FABRIC genannt, aber ich war zu langsam. ;-.)

Man hat das etrwas abstrakter als Objekt betrachtet. Der Typ eines Objektes wird klassisch als Class bezeichnet. Die Variable vom Typ einer Klasse ist dann eine Instanz.
Nur zur Klarstellung: in einer Klassendefeinition kann man Datentypen und Funktionen so anlegen, wie man Datentypen in einem Record oder einer Struct-Anweisung anlegen kann.


-> Das sollte einem die Angst vor den angebliche "anderen" Objekten nehmen. ;-)


Die Planung der Umsetzung von Anforderungen an ein Programm:

Das führt dann relativ schnell zu einer etwas anderen Planungsweise. Bisher hat man überlegt "ich habe die daten A bis x und benötige als Ergebnis Z, was muss dabei vom Start bisn zum Ergebnis passieren?". Die Denkweise ist eher sequentiell von Oben nach Unten gerichtet.
Objekte legen nun einen etwas anderen Ansatz der Lösungsfindung nahe. Man hat einen Datensatz und kann nun überlegen, wie man diesen manipulieren kann. Im Einfachsten fall, kann man Daten in A nur übergeben und auslesen. Nichts anderes also, als auf eine Variableninhalt zuzugreifen oder etwas dort abzulegen.
Der Trick ist nun, dass man das über Funktionen erledigt. Das bedeutet dann in der Praxis, dass man eigentlich nicht wissen muss, wie A nun wirklich deklariert ist. Über die Funktionen zum Auslesen und Übergeben von neuen Werten hat man die Typdeklaration komplett entkoppelt. Man könnte die Datenverwaltung im Hintergrund ändern (z.B. von einem statischen Array in eine dynamische Liste), ohne dass man den Rest des Programmes anfassen muss.


Vererbung:

Ich habe es angesprochen: die "unsichgtbare" Änderung der Funktionen eines Objektes ist denkbar und möglich. Man nutzt nun die nette Möglichkeit, dass Klassen eigentlich nur Typdefinitionen sind, die man in anderen klassen als Variable einbinden kann.
Hier hat man nur eine nette Neuerung eingebaut: man kann Klassen ableiten (aus einer vorhandenen Klasse erzeugt man einen neue). In der abgeleiteten Klasse kann man dann die Deklarationen an Variablen oder Funktionen erweitern UND auch ändern (überschreiben! Das nennt man Vererbung.


Wechselbalg?

Und noch besser wird es, wenn man daran denkt, dass Instanzen quasi Variablen vom Typ einer Klasse sind. Natürlich kann man hier auch mit zeigern arbeiten, ergo kann man eine Instanz als Parameter an eine Funktion übergeben. dabei kann man dann natürlich alle Funktionen und Variablen in der Klasse nutzen.

Und jetzt arbeiten wir die Vererbung ein. :-)

Haben wir eine Parameter vom Typ einer Klasse, dann können wir dort auch Instanzen von abgeleiteten Klassen übergeben! Dabei kann man die Funktionen der klasse so deklarieren, dass sie die Funktion der abgeleiteten Klasse ausführen.

Was das bedeutet? Statten wir alle unsere Klassen mit der Funktion SAVEDATA(filename:text) aus, dann können wir diese Funktion nutzen und die Daten der jeweiligen Klasse so speichern, wie wir sie brauchen (das Programmiert man dann in der Funktion der Klasse). Packen wir eine Klasse als Parameter in Funktion STOREDATA(), dann kann uns egal sein, welche Klasse genau übergeben wird. Wir brauchen nur SAVEDATA() aufzurufen und die Klasse speichert ihre Daten ab.


Denken in Objekten:

Die Umstellung ist dann zwar radikal, aber doch eigentlich nicht besonders überraschend: um Objekte effektiv nutzen zu können, überlegt man sich am besten, wie man die Datenstrukturen aufbauen muss. Dabei kann man sich direkt überlegen, ob und wie man die Objekte ableiten kann.
Dabei helfen die Methoden (Funktionen) zur Bearbeitung der Daten: man versucht sie zu vereinheitlichen und nur die Änderungen für die Ableitungen festzulegen.



Ereignisgesteuerte Programmierung

Das ist ein zweiter Punkt, der oft direkt mit der Objektorientierung verbunden wird. Meiner Meinung nach ist das aber falsch. Man kann auch ohne Hilfe von Objekten ereignisgesteuert programmieren.
Es geht dabei darum, dass moderne Betreibssysteme wie Windows in ihren Useroberflächen nicht mehr mit einfachen Schleifen arbeiten können.
Man nutzt hier vielmehr Callback-Funktionen. Jedes Programm muss eine solch Funktion besitzen, um auf Nachrichten über Ereignisse vom Betreibssystem informiert werden zu können.
Ich stelle mir das so vor: wenn ein Programm starten, wird es beim betriebssystem angemeldet und übergibt seine Callbackfunktion. Das Betriebssystem ruft dann zyklisch oder bei Bedarf diese Funktion auf, schickt einen Nachrichtendatensatz mit.

Das angesprungende Programm muss dann die Nachricht auswerten und auf die übermittelte nachricht reagieren.

Die Nachrichten können solche Dinge wie "Zeiche deine Oberfläche neu", "Taste gedrückt" oder "Mausklick auf Position X/Y" sein. Die Programme selbst können nachrichten absetzen, z.B. wenn sie einen mausklick erhalten haben und festgestellt haben, dass damit der Programmschliessenbutton gedrückt wurde. Dann wird das Programm seine internen Programmendefunktionen ausführen und danach das Betriebssystem über eine neue Nachricht informieren, dass es abgemeldet werden will.

In allen modernen Entwicklungsumgebungen wie Visualbasic, VisualC++ oder Delphi ist ein grossteil dieser nachrichtenbehandlung in der Klassenbibliothek gekaspelt (versteckt). Hier liegt dann eine Programmsteuerung vor, die gewisse Funktionen des Basisobjektes aufruft, wenn ei bestimmtes Ereignis (eine Nachricht) eintritt.


Alles zusammen:

Die neue Denke liegt also darin, nicht mehr von Oben nach Unten zu planen, sondern die Sache in Datentypen, Methoden UND auftretende Ereignisse zu teilen.

Beispiel:

Wir wollen die Werte A und B addieren und das Ergebnis ausgeben.

Klassisch:

- Variablen A und B deklarieren
- beide Werte einlesen
- multiplizieren
- Ergebnis ausgeben

Neu:

Was müssen wir verwalten?

Eingabefelder: A und B (das sind auch gleich die Variablen!)
Ausgabefeld: Ergebnis

Das ganze muss berechnetw erden, dazu wird es einen Button geben. Das Programm muss also noch einen Button besitzen, neben des bereits definierten drei Feldern. Der Button ist natürlich auch ein Objekt.

Die Berechnung erfolgt dann bei Betätigung des Buttons.
Der Button besitzt eine Methode, die automatisch vom Betrienssystem aufgerufen wird, wenn die Maus den Button betätigt (die Erkennung und Steuerung der Mausklicks und die Verarbeitung der eingehenden Nachricht erledigt bereits komplett die verwendete Klassenbibliothek, die wir automatisch nutze (müssen).

Was wird dann umsetzen müssen ist folgendes:

Wir legen ein Programmobjekt an (i.d.R. bedeutet das ein Fensterobjekt im Editor aufziehen). Dort fügen wir drei Felder und den Button ein. Der Button wird eine Methode OnClick() besitzen, hier programmieren wir die Bereichnung (Werte aus den Eingabefeldern auslesen, addieren und das Ergbis im Ausgabeeld speichern).

Das war's, der Rest erledigt der Compiler dank der vorhandenen Klassenbibliothek. :-)


Ich hoffe, damit ahbe ich alle Klarheiten beseitigt. ;-)

Bis dann
Andreas

PS: Wie gesagt, es ging mir beid er sache nicht um die reine Lehre. Rechthaben dürfen andere. ich finde das wichtigste, ist die Angst vor dem "Anderssein" der Objektorientierung zu nehmen. Es ist neu, aber nicht so neu, dass man damit gar nicht klarkommen würde. Die Umstellung, die man bei sich selbst vornehmen muss ;-), ist gar nicht so schwierig.

[Diese Nachricht wurde nachträglich bearbeitet.]

Hier steht was ueber mein altes Hard- und Softwaregedoens.
bei Antwort benachrichtigen
oha KoRny Boy