![]() |
Re: Abstract oder überhaupt nicht?
Zitat:
|
Re: Abstract oder überhaupt nicht?
Zitat:
|
Re: Abstract oder überhaupt nicht?
Der erste Gedanke ist manchmal der Beste ! Für eigene Zwecke ist Abstract Unfug. ABSTRACT ist für Komponenten-Entwickler gedacht. Die deklarieren etwas undefiniertes als abstract, um eben lediglich einen (sinnleeren) Namen zur Verfügung zu stellen und eine DCU auszuliefern. Du wirst wohl schon beim Testen gemerkt haben, daß es überall kracht, weil die Methoden eben undefiniert sind und man immer dran denken muß, sie mit Leben zu erfüllen. :???: Bei eigenen Komponenten usw. macht das kaum Sinn.
|
Re: Abstract oder überhaupt nicht?
Was Hänschen nicht lernt, lernt Hans nimmermehr... Warum sollte man auf gute Designprinzipien verzichten, nur weil man den Code nur selbst benutzt? Nachher gewöhnt man sich noch dran und kommt draußen in der weiten Welt nicht klar ;)
Wie Jelly und onlinekater sehr schön beschreiben, können abstrakte Methoden durchaus auch in der internen Entwicklung sinnvoll sein. Je umfangreicher ein Projekt ist, desto wichtiger ist es, dass alles ordentlich organisiert ist und nicht à la "die Funktion gibt's nicht, füg ich sie eben da ein, wo ich sie gerade brauche". In vielen anderen Sprachen sind Klassen, die abstrakte Methoden enthalten, automatisch abstrakt und können nicht instanziiert geben. Da "kracht" es also nicht, sondern es gibt einen Kompilierfehler. |
Re: Abstract oder überhaupt nicht?
Zitat:
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:
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:
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.
type
TTastenDruckBeobachter = class(TObject) public keyDown(const Key : Integer); virtual; abstract; end; 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:
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.
type
TBeobachtestObjekt private FBeobachter : TObjectList; public procedure registerTastenDruckBeobachter(beobachter : TTastenDruckBeobachter); 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 |
Re: Abstract oder überhaupt nicht?
Zitat:
Delphi-Quellcode:
das ist eine astreine abstrakte klasse(ist natürlcih D2006, eventuell gibts das zuvor noch gar nicht). DoSomeThingGeneric ist bereits implementiert, und greift vielleicht auf FElement zu. Damit kann ich bestimmte Sachen bereits in dieser Basisiklasse implementieren. Die Folgeklassen sollten dann eben YouImplementThatPlease überschrieben.
type
TSomething = class abstract (TObject) private FElement: TSomethingElse function DoSomeThingGeneric; function YouImplementThatPlease; virtual; abstract; public constructor Create(genericparam: TType); virtual; abstract; end; Damit kann man auch, wenn man nur weiss, dass ein Objekt von TSomeThing abstammt, YouImplementThatPlease aufrufen (auf die Gefahr hin, dass man einen abstract error erntet). So etwas ist nicht nur in Komponenten sinnvoll, sondern überall, wo man auf sachen zugreifen willl, von denen man zur Compiletime nicht genau weiss, wie sie später aussehen. (Ich verwende so etwas im übrigen gerade) @Der_Unwissende: Ja, PlugIns, das ist hier wohl das Stichwort. |
Re: Abstract oder überhaupt nicht?
... und ein Geist wirds wohl nie lernen. :mrgreen: Man fängt nicht bei OOP mit TObject oder so was an (obwohl das oft zu sehen ist), sondern sucht sich einen geeigneten Vorfahrtyp aus und fügt neue Methoden, Felder usw. bei Bedarf hinzu. Besteht an der Stelle kein Bedarf, dann macht es keinen Sinn, sie schon bei Adam und Eva leer (also abstract) zu deklarieren, sondern eben erst ab der Hierarchiestufe, ab der sie benötigt werden. Im eigenen Programm weiß man normalerweise was wo gebraucht wird und braucht nicht unnötige Platzhalter mit rumzuschleppen. Sofern bereits klar ist, daß tatsächlich noch etwas fehlt, dann besteht auch an der Stelle kein direkter Zwang, abstract zu benutzen. Man kann den Prozedurrumpf auch leer lassen und später eben konkret besetzen. Wer ein begin end; einsparen will, der muß dann eben abstract benutzen.
|
Re: Abstract oder überhaupt nicht?
Zitat:
Langsam sollte doch deutlich geworden sein, dass solche Pauschalisierungemn meist fehl am Platz sind. Das hat doch auch schon die goto-Diskussion gezeigt. |
Re: Abstract oder überhaupt nicht?
Zitat:
Zitat:
1. Nun müsste ich an einer Stelle wo ich dies allgemein abfragen will, jeweils Adam und auch Eva kennen und testen, habe ich nun eine Eva oder eine Adam Instanz und dann auf diese Casten, um dann die Methode aufzurufen um das Geschlecht zu erhalten. 2. Ich definiere mir eine virtuelle Funktion im Vorfahrtyp von Adam und Eva. Die muss ich hier auch gleich implementieren - aber was gebe ich zurück? Nichts? Oder gebe ich nun männlich oder weiblich zurück? Was nur? Ich grübel noch ein paar Jahre ... 3. Nochmal das gleiche wie in 2.: Ich füge eine virtuelle Methode Geschlecht ein. Ich habe mich auf ein "Standardgeschlecht" geeinigt: männlich. Nun hat aber der Entwickler von Eva geschlafen und die virtuelle Methode nicht überschrieben und schon bekomme ich bei Adam und Eva als Geschlecht männlich zurück geliefert. 4. Ich definiere eine abstrakte Methode Geschlecht in der Basisklasse von Adam und Eva. Dadurch kann ich das Geschlecht auch schon in der Basisklasse abfragen und benutzen in anderen Methoden der Klasse und ich kann mir sicher sein, dass die späteren Leute auch immer ihr richtiges Geschlecht angeben, da eine abgeleitete Klasse die Methode implementieren muss. Was ist davon nun am besten? Für mich kommt nur 4. in Frage. Ich kann sicher sein, dass ich die richtige Information bekomme und ich kann das Geschlecht ganz abstrakt abfragen. Programmierfehler wie falsche Informationen oder schlimmer noch vergessene Implementation durch vergessene Überschreibungen von Methoden, fallen sofort auf (EAbstractException). Somit habe ich doch die meiste Sicherheit bei dem 4. Punkt. Die Exception zu den nicht implementierten abstrakten Methoden ist ein Hinweis zur Entwicklung und keiner wird eine abstrakte Methode einfügen und dann das Programm keine 5 Minuten später ausliefern, so dass ein Kunde das bekommt. Durch das QM sollte vorher mindestens ein paar Tests durchlaufen werden, wo genau solche Meldungen auftreten und den Misstand im Code aufzeigen. |
Re: Abstract oder überhaupt nicht?
Zitat:
Zitat:
Jedenfalls ändern sich da mal Ansprüche, ein paar Dinge sollen dann doch rein oder eben nicht und wenn's gut läuft, möchte man vielleicht etwas Ähnliches. Gerade wenn du hier versuchst eine GUI gleich zu halten (Wiedererkennung ist wichtig), kommt es schnell dazu, dass du gerne auf OOP (und damit abstrakte Methoden) zurückgreifst. Zitat:
@ALLE OPs, könnte in diesem Thread ein Warnschild angebracht werden, dass hier Meinungen geäussert werden, die sich kein Anfänger anschauen sollte! Ich meine es muss ja nicht auf den konkreten Beitrag hingewiesen werden, aber wenn jmd. so was liest und das dann auch noch glaubt!!! Das kann man doch gar nicht wieder gut machen! [Edit] Begriff korrigiert [/Edit] |
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:04 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz