Delphi-PRAXiS
Seite 3 von 4     123 4      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Delphi Meine Probleme mit Delphi-OOP ... (https://www.delphipraxis.net/166632-meine-probleme-mit-delphi-oop.html)

himitsu 24. Feb 2012 01:20

AW: Meine Probleme mit Delphi-OOP ...
 
Liste der Anhänge anzeigen (Anzahl: 1)
Praktisch gesehn, werden diese globalen Form-Variablen garnicht benötigt, welche Delphi standardmäßig anlegt.

Ich würde mir wünschen, wenn es dieses CreateForm auch ohne diesen Var-Parameter geben würde. Aber mit einer temporären Variable in der DPR, könnte man dieses auch lösen.
Vorallem in einem Programm mit nur einem automatisch erstellten Form, gibt es IMHO absolut keine Daseinsberechtigung für diese Variable und ohne diese gäbe es viele (Anfänger)Probleme ganicht erst.

PS: Das angehängteDemoprojekt enthält einen Fehler, wie es genau so schon vorgekommen ist, bei einem Anfänger/Schüler, letztes Jahr hier in der DP.
Und er zeigt ein großes Problem, welches mit globalen Variablen auftreten kann, wenn sie nicht eindeutig verwendet, sondern mehrmals und/oder an mehreren Stellen genutzt werden.

Ach ja, ich suche noch eine einfache Demo, für eine globale Zählvariable, welche in mehreren Funktionen genutzt werden und sich so gegenseitig beeinflussen, was mit lokalen Schleifenvariablen nicht passieren würde. Falls jemand was kennt.... (mit ist der Thread aus'm letzten/vorletzen Jahr nicht wieder eingefallen, wo sowas mal aufgetreten ist)

Gustav.R 24. Feb 2012 02:43

AW: Meine Probleme mit Delphi-OOP ...
 
Zitat:

Zitat von himitsu (Beitrag 1152602)

Ach ja, ich suche noch eine einfache Demo, für eine globale Zählvariable, welche in mehreren Funktionen genutzt werden und sich so gegenseitig beeinflussen, was mit lokalen Schleifenvariablen nicht passieren würde. Falls jemand was kennt....

Dir ist schon klar, daß Du müde bist:
http://www.youtube.com/watch?v=ODlmEjZ8UFA

:wink:

freak4fun 24. Feb 2012 10:25

AW: Meine Probleme mit Delphi-OOP ...
 
Vielleicht hilft das hier weiter: Klick! :)

einbeliebigername 24. Feb 2012 10:29

AW: Meine Probleme mit Delphi-OOP ...
 
Hallo,

Zitat:

Zitat von MGC (Beitrag 1152598)
Daher kannst Du entweder bereits den originalen Konstruktor überschreiben und erweitern, ein override udn ein overload hinzufügen und dann einen weiteren Konstruktor mit overload hinzusetzen, wenn seine Parameterliste sich vom ersten unterscheidet.

Hast du das schon mal gemacht. Also ich habe das jetzt bei dir, aufbauen auf meinem obigen Code, so verstanden, das folgendes keine Warnung bringen soll:
Delphi-Quellcode:
  TTest5= class(TTest1)
    procedure Test; overload; override;
    procedure Test(const A: Integer); overload;
  end;
Kommt aber trotzdem die Warnung:
Code:
[DCC Warnung] MethodTracerUnit1.pas(32): W1010 Methode 'Test' verbirgt virtuelle Methode vom Basistyp 'TTest1'
Zitat:

Zitat von trebor90 (Beitrag 1152592)
@einbeliebigername:
Ok, dann ist das anders als zum Beispiel in C++. Da muss man Methoden nicht erst reintroducen, um eine Methode einer Basisklasse ueberladen zu koennen. Man ueberlaedt sie und - fertig.
Das heisst also, der Designer der Basisklasse legt in Delphi fest, ob man seine Methoden "einfach so" (ohne reintroduce) ueberladen kann?? Indem er hinter die betreffenden ein overload setzt????!

Bei C bzw. C++ ist alles ein wenig anders. In C ist jede Funktion und somit in C++ auch jede Methode sofort überladbar. Das heißt man kann folgendes machen:
Code:
  void Test;
  void Test(int A);
In Delphi ist jede normale Funktion, Prozedur, Methode nicht überladbar. Will man überladen muss man bei jeder Version ein overload mit angeben. Folgendes geht deswegen so nicht:
Delphi-Quellcode:
    procedure Test;
    procedure Test(const A: Integer);
Der Kompilier wirft da einen Fehler. Auch so:
Delphi-Quellcode:
    procedure Test;
    procedure Test(const A: Integer); overload;
und so gibt es einen Fehler:
Delphi-Quellcode:
    procedure Test; overload;
    procedure Test(const A: Integer);
Erst so funktioniert das Überladen:
Delphi-Quellcode:
    procedure Test; overload;
    procedure Test(const A: Integer); overload;
Und weil das auch bei Vererbung so ist, braucht man für jede andere Version des Create-Constructors bei Komponenten ein
Delphi-Quellcode:
reintroduce;
.

Zitat:

Zitat von trebor90 (Beitrag 1152592)
--> Und in C++ muss eine Methode auch nicht virtuell sein, dass ich sie ueberschreiben kann. Das geht auch ohne.

Kannst du das mal bitte mit einem Beispiel verdeutlichen wie das funktionieren soll. Bei mir ist C++ schon eine Weile her, aber ich meine auch in C++ kann man nur virtuelle Methoden überschreiben.

Zitat:

Zitat von trebor90 (Beitrag 1152592)
Problem aber immer noch:
Was ist der Unterschied zwischen Verdecken und Ueberschreiben??
Ich kenne sowas wie "Verdecken" gar nicht.

Ich meine Verdecken ist das:
Delphi-Quellcode:
  TTestA= class
    procedure Test;
  end;

  TTestB= class(TTestA)
    procedure Test(A:Integer);
  end;
Das Test von TTestB verdeckt das Test von TTestA. Sprich folgendes lässt sich nicht kompilieren:
Delphi-Quellcode:
  ...
  B: TTestB
  ...
  B.Test;
  ...
Die Fehlermeldung wäre:
Code:
[DCC Fehler] MethodTracerUnit1.pas(119): E2035 Nicht genügend wirkliche Parameter
einbeliebigername.

MGC 24. Feb 2012 11:36

AW: Meine Probleme mit Delphi-OOP ...
 
Zitat:

Zitat von MGC (Beitrag 1152578)
In wie weit man hinter den ersten Konstruktor allerding override und overload zugleich setzen kann, weiß ich jetzt aus dem Stehgreif auch nicht, werde ich aber mal testen.

Ich zitiere mich hier mal selbst. Ich habe bereits im Thread mitgeteilt, dass ich mir nicht sicher bin ob es mit override und overload funktioniert. Hab ees jetzt getestet und bin in der Tat zu dem Schluss gekommen, dass man reintroduce verwenden muss, um überladene Methoden einzusetzen.

Was ich aber dennoch nicht ganz verstehe, weshalb eine feste Definition innerhalb einer Sprache nicht einfach hingenommen werden kann. Es gibt ja auch noch die Unterschiede bei div zwischen C++ und Delphi, wobei ich in dieser Hinsicht sagen muss, dass mir Delphi da besser gefällt. Auch dass es bei Delphi in der Grundeinstellung keine Header-Dateien gibt wie in C++ wurd enicht bemängelt, obwohl man dann von ganz unten bis nach ganz oben scrollen mus, anstatt einfach in den Header zu sehen wenn man Variablen oder Deklarartionen nochmals bearbeiten möchte.

himitsu 24. Feb 2012 12:44

AW: Meine Probleme mit Delphi-OOP ...
 
overload = überladen
override = überschreiben

überladen = gleichzeitig mehrere Methoden mit gleichem Namen, bzw. alte aus Vorfahren Methode nicht verdecken. (absichtliches Verdecken wird mit reintroduce angeben)
überschreiben = virtuelle (virtual) oder dynamische (dynamic) Methode des Vorfahren überschreiben, also den Eintrag in der VMT ändern.


scrollen ... dafür ibt es Listen und Tastenkürzel, im schnell hin- und herzuspringen, wie z.B. Strg+Shift+Hoch oder +Runter

MGC 24. Feb 2012 16:18

AW: Meine Probleme mit Delphi-OOP ...
 
@himitsu: Ist dies eine allgemeingültige Definition und somit auch auf Delphi übertragbar? Ich wäre jetzt sehr dankbar, wenn Du mir erklären würdest, warum der Delphi-Compiler dies anscheinend anders sieht.

Abgesehen davon, wenn man mit reintroduce absichtlich eine Methode überdeckt, aber mit inherited dafür sorgt, dass die originale Methode dennoch ausgeführt wird, was soll daran so schlimm sein?
Ich verstehe eben nach wie vor nicht, wen es gewisse Regeln zu geben scheint, an die man sich einfach zu halten hat, warum es so schwer ist genau dies zu tun?

Ich möchte hier niemandem mit dem Finger drohen, wie es anscheinend rüberkommt. Denke aber immer daran, dass die ursprüngliche Definition der OOP zugunsten der Praktikabilität nicht vollkommen umgesetzt wurde (z.B. bei der Polymorphie).

Zitat:

Aus Wikipedia - Prinzipien Objektorientiertes Design (Liskovsches Substitutionsprinzip)
[...]Damit ist garantiert, dass Operationen vom Typ Superklasse, die auf ein Objekt des Typs Subklasse angewendet werden, auch korrekt ausgeführt werden. Dann lässt sich stets bedenkenlos ein Objekt vom Typ Superklasse durch ein Objekt vom Typ Subklasse ersetzen. Objektorientierte Programmiersprachen können eine Verletzung dieses Prinzips, das aufgrund der mit der Vererbung verbundenen Polymorphie auftreten kann, nicht von vornherein ausschließen. Häufig ist eine Verletzung des Prinzips nicht auf den ersten Blick offensichtlich.[...]

himitsu 24. Feb 2012 16:26

AW: Meine Probleme mit Delphi-OOP ...
 
Wegen den anderen fragen schau ich dann nochmal nach.

Aber reintroduce schaltet eigentlich nur die Compilerwarnung ab.

Wenn man eine Methode verdeckt, dann wird man vom Compiler gewarnt. Und hat man absichtlich verdeckt, dann kann man das über reintroduce auch so markieren und weg ist die Warnung.



Ob die verdeckte Methode intern dann via inherited oder sonstwie aufberufen wird, ist dabei unwichtig.
Das Verdecken bezieht sich nur auf die äußere Schnittstelle, also das Interface (Deklaration) und nicht die Implementation (Code).

MGC 24. Feb 2012 16:40

AW: Meine Probleme mit Delphi-OOP ...
 
@himitsu: Besten Dank, wird notiert. Vielleicht nehme ich auch viel zu viel einfach als gegeben hin.

himitsu 24. Feb 2012 19:51

AW: Meine Probleme mit Delphi-OOP ...
 
Zitat:

Ist dies eine allgemeingültige Definition und somit auch auf Delphi übertragbar?
Ob es allgemeingültig ist, weiß ich nicht, was ich würde mal blind "ja" denken.
Overload, Override ist zumindestens in Delphi/Pascal so umgesetzt.


Virtual und Override ist so:

Gibt man in einer Klasse virtual für eine Methode an, dann wird dafür, in/ab diesem Typ ein Eintrag in der VMT angelegt.
Wenn man jetzt eine Variable mit diesem Typ anlegt, dann kennt dieser Typ seine VMT.

Nun könnte man in einer Variable auch einen Nachfahren dieses Typen abspeichern.

Ist in dem abgeleiteten Typen diese Methode überschrieben, dann wird das in der VMT vermerkt.
Damit kennt dann auch der Vorfahr den Zeiger zur neuen Methode, da es ja in der VMT drinsteht.

Wurde diese Methode aber nur verdeckt (egal ob sie Virtual ist oder nicht), dann kennt der Vorfahr diesen Zeiger nicht und kann damit immer nur seine Methode aufrufen.

Aus diesem Grund sind alle VCL-Komponenten von TComponent abgeleitet, wo vorallem der Constructor virtuell ist,
sowie bei allen Klassen der Destructor virtual ist.

Auf diese Weise kann die VCL den richtigen Constructor laden und auch immer der richtige Destructor ausgeführt werden, da der Vorfahre diese kennt.


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:40 Uhr.
Seite 3 von 4     123 4      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz