Zitat von
Neutral General:
erm..*hust*
Es tut mir leid wenn es jetzt so rübergekommen ist das ich kein
OOP könnte.. *hust*
Erstmal dazu, warum die Rechtfertigungen? Es ist doch nicht schlimm, wenn du die
OOP noch nicht vollständig (und in allen Details) kennst. Abstraktion ist hier eines der wichtigsten Grundprinzipien und es dauert nun mal ein Weilchen, bis man hier die Vorteile verstanden hat. Ich seh immer wieder Beiträge, von Leuten die wirklich keine Ahnung von
OOP haben und es ist vollkommen ok!
Wüßten alle alles, so wäre die
DP leer, auch nicht das Wahre!
Die Grundlagen zu kennen und sie zu verstehen sind ausserdem noch zwei verschiedene Dinge. Es ist doch nur löblich, dass du nachfragst! Unwissenheit ist doch keine Schande, nichts an ihr zu Ändern schon!
Zitat von
Hansa:
Der erste Gedanke ist manchmal der Beste ! Für eigene Zwecke ist Abstract Unfug. ABSTRACT ist für Komponenten-Entwickler gedacht.
Sorry, aber das ist doch totaler Scheiß! Was sind denn die eigenen Zwecke? Also ich denke jeder Komponentenentwickler zählt das Entwickeln von Komponenten dazu.
So, ein wenig zum Thema abstrakte Methoden. Es gibt wirklich sehr viele Fälle, wo du eine Zusicherung durch abstrakte Methoden möchtest. Wie hier schon gesagt wurde (auch von dir) muss die Methode im verwendeten Nachfahren implementiert werden. Das Abstrakte hier ist, dass du nicht weißt wie. Damit ist die Implementierung ganz einfach austauschbar.
Ganz wichtig ist dieser Vorteil immer dann, wenn du an einem großen Projekt mitarbeitest. Da kommt es immer wieder vor, dass du eine Funktion brauchst, die aber noch gar nicht implementiert ist. Die eigentliche Anwendung, die programmiert werden soll, besteht i.d.R. aus sehr vielen verschiedenen Teilen. Du kennst vielleicht die Trennung MVC (Modell, View, Controller)? Natürlich gibt es noch ganz andere Einteilungen und jedes Problem kann aus kleinen Teilen bestehen. Nicht alle sind gleich schwer (beanspruchen gleich viel Zeit). Hast du eine abstrakte Methode, kannst du deine Klasse mit dieser Methode schon testen, ohne dass du in hier eine fertige Implementierung brauchst. Insbesondere kannst du hier auch einen Dummy schaffen und mit dem arbeiten. Ist irgendwann die echte Implementierung fertig, so kannst du die beiden einfach austauschen.
Gut, dass klingt nun auch nicht gerade nach "für eigene Zwecke", aber es ist nur eines von wirklich vielen Beispielen.
Eines dass dir auch für deine Zwecke begegnen könnte wäre das folgende:
Du möchtest einen Editor bauen. Und sagen wir mal (ganz kreativ), der soll plugin-fähig sein. Nun ja, jetzt hast du das Problem, dass deine Plugins nur funktionieren, wenn sie mitbekommen was im Editor passiert. Dass du für ein Plugin noch gar nicht weißt, was dieses mit dem Inhalt des Editors macht, dürfte auch klar sein, hier siehst du schon, dass es nicht ohne Abstraktion weiter gehen kann.
Sagen wir mal sehr stark vereinfacht, du möchtest, dass Plugins auf einen Tastendruck reagieren können. Dazu möchtest du die wissen lassen, wann eine Taste im Editor gedrückt wurde. Welche Möglichkeiten hast du also?
Klar, du könntest einfach Hooks benutzen, allerdings wird dann auch kein Entwickler (aus dir) Plugins bauen. Haut es also nicht raus.
Windows-Messages, auch nicht das Wahre, da muss schon wieder der Plugin-Entwickler umständlich drauf reagieren, selbes Problem.
Wie macht Delphi das gleich? Hm, hier gibt es Methodenzeiger (kannst
ein OnKeyDown impelementieren). Dummerweise sollen aber alle Plugins mitbekommen, wenn die Taste gedrückt wurde. Natürlich kannst du jetzt ein Array von Methodenzeigern verwenden, aber dass ist halt nicht
OOP.
In der
OOP gibt es halt keine expliziten Zeiger.
Hier würdest du eher zum Observer-Pattern greifen. Dies ist recht einfach. Du hast ein Beobachtes Objekt (in diesem Fall der Editor) und beliebig viele Beobachter (die Plugins). Ein Beobachter kann sich beim Beobachteten für ein Ereignis anmelden. Tritt dieses Ereignis ein, so merkt es der Beobachtete und informiert alle registrierten Beobachter.
In dem Beispiel mit dem Editor könntest du dabei einfach eine abstrakte Klase nehmen, die Tastendrücke beobachtet.
Delphi-Quellcode:
type
TTastenDruckBeobachter = class(TObject)
public
keyDown(const Key : Integer); virtual; abstract;
end;
Wie du hier siehst, hat diese Klasse nur eine Methode und die ist abstrakt. Jedes deiner Plugins, dass von dieser Klasse erbt, muss die implementieren. Was für Plugins das sind, weißt du aber noch gar nicht, nur dass diese Methode vorhanden ist.
Ja, das ist auch alles was du jetzt beim beobachteten Objekt ausnutzt. Du schaffst einfach eine Methode, mit der sich Beobachter für Tastendrück anmelden können.
Delphi-Quellcode:
type
TBeobachtestObjekt
private
FBeobachter : TObjectList;
public
procedure registerTastenDruckBeobachter(beobachter : TTastenDruckBeobachter);
In dieser Methode merkst du dir einfach die Instanz, die sich anmeldet. Hier könntest du z.B. eine TObjectList verwenden. Natürlich sollte man auch die Möglichkeit des deregistrierens schaffen, aber hier erstmal egal.
So, jedes Plugin erbt nun von TTastendruckBeobachter und macht was auch immer es machen will, wenn eine Taste gedrückt wird. Welche Taste gedrückt wurde, steht ja in der Methode, wer die Methode aufruft und mit was für einem Parameter, weiß das Plugin wiederum nicht.
Tritt das Ereignis ein, so muss das Beobachtete Object nur noch die keyDown Methode von jedem gespeicherten Beobachter aufrufen. Als Argument wird natürlich die gedrückte Taste übergeben.
Ich denke so etwas kann einem auch mal in eigenem Code begegnen. Klar, in gewisser Weise schafft man hier eine Komponente, aber das geht in jedem Programm sehr sehr schnell.
Gruß Der Unwissende