Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi vs. JAVA , Class Design (https://www.delphipraxis.net/207825-delphi-vs-java-class-design.html)

bernhard_LA 6. Mai 2021 22:01

Delphi-Version: 5

Delphi vs. JAVA , Class Design
 
Liste der Anhänge anzeigen (Anzahl: 1)
ich bin gerade am portieren eines JAVA codes nach Delphi , und habe eine Verständnisproblem für folgende Klassenbeziehung im Codebeispiel.
Die Procedure B kann ich in Delphi nicht aufsetzen/compilieren, weil ja TClassB erst später definiert wird.
Geht so was in JAVA und in Delphi nicht ?


Delphi-Quellcode:
program Project2;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils,
  Types,
  classes;

Type  TClassA = class

       procedure p1 ;
       procedure p2 ;

      //  procedure B (anyClass : TClassB);

end;


Type  TClassB = class

       FclassA : TClassA;

       procedure B_p1 ;
       procedure B_p2 ;

end;




{ TClassA }

procedure TClassA.p1;
begin

end;

procedure TClassA.p2;
begin

end;

{ TClassB }

procedure TClassB.B_p1;
begin

end;

procedure TClassB.B_p2;
begin

end;

begin
  try
    { TODO -oUser -cConsole Main : Insert code here }
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

OlafSt 6. Mai 2021 22:08

AW: Delphi vs. JAVA , Class Design
 
Delphi-Quellcode:
type
   TClassB = class;
   TClassA = class
      procedure B (anyClass : TClassB);
      ...
   end;

   TClassB = class
      ...
   end;

himitsu 6. Mai 2021 22:16

AW: Delphi vs. JAVA , Class Design
 
Das nennt sich Forward-Deklaration. Es geht bei Klassen und ähnlich auch Pointer-Typen.

Und es muß aber immer im selben TYPE-Block stehen.
Oben hast du bei dir zwei TYPE. (jede Klasse einzeln)

bernhard_LA 6. Mai 2021 22:27

AW: Delphi vs. JAVA , Class Design
 
OK, verstanden :) ;
d.h. ich müsste die Klassen welche jetzt noch in verschieden units stehen in eine unit kopieren.
In Java standen die Klassen halt auch in verschiedenen *.java Dateien, waren nur im selben package

himitsu 6. Mai 2021 22:49

AW: Delphi vs. JAVA , Class Design
 
Ich weiß nicht wie Java arbeitet, aber z.B. C/C++ "included" quasi alles zu einer rießengroßen Unit,
bei Delphi bleiben die Units für sich getrennt und werden einzeln kompiliert.

Wenn es sich nicht wie hier, im Interface, gegenseitig referenziert, dann kann man auch Units kreuzverlinken (zwei Units, die sich gegenseitig im USES des Interface/Implementation und die Andere im USES nur der Implementation einbinden)

Bei Klassen, die sich gegenseitig brauchen und wo sie bede im Interface stehn müssen, die können nur in der selben Unit, im gleichen Type stehen.
Ausnahme: Die eine Klasse wird nach dem selben Muster implementiert, nur halt abstakt, also nur die eine Funktionsdefinition B als "virtual; abstract;"
und dann die Ableitung mit dem "overload;" und allem Anderen kann in eine andere Unit.

Phoenix 7. Mai 2021 05:58

AW: Delphi vs. JAVA , Class Design
 
Delphi hatte damals klassischerweise (und aus Performance-Gründen) einen Single-Pass Compiler. Das heisst, der ist einmal von vorne bis hintern durch alle Deine Files durch in der Reihenfolge wie sie im Projekt angegeben dann durch andere Dateien inkludiert wurden, und konnte zum Zeitpunkt X immer nur die Typen verwenden, die bis dahin schon bekannt waren. Unbekannte Typen etc. kann der Compiler daher ungeheuer Schnell anmeckern. Das ist zwar seit dem Umstieg auf einen neuen Compiler leicht anders, die Regeln sind aber beibehalten worden.

Andere Sprachen wie Java oder auch C# haben mit Multi-pass-Compilern angefangen. Dort geht der Compiler erst einmal durch alles durch und baut sich eine Liste mit allem was er schon gesehen hat, und bei Funktionen die Typen benutzen die er noch nicht kennt setzt er Platzhalter ein. Wenn er den Typen dann wirklich sieht, ersetzt er den Platzhalter. Erst wenn der Compiler dann am Ende immer noch offene Platzhalter hat, wirft er einen Fehler. Das macht den Compiler aber ein gutes stück komplexer und auch langsamer. Der eigentliche Code in den Methoden wird dann in einem zweiten Durchlauf durch das gesamte Projekt übersetzt.

C oder C++ lösen das Problem nochmal anders, in dem die Deklarationen in die sogenannten Header-Files kommen und in anderen Dateien dann der eigentliche Code.

Grundsätzlich sind zirkuläre Verweise (A nutzt B und B nutzt A) aber etwas, was man nach Möglichkeit vermeiden sollte. Ein Anwendungsgebiet wo sie Sinn machen sind doppelt verkettete Listen, und unter Umständen Objektmodelle die Datenbankstrukturen abbilden (Tabelle A hat einen Verweis auf B, wobei ein Eintrag in B auch wieder auf Einträge in Tabelle A verweisen kann). Aber auch da sollte es möglichst sparsam eingesetzt werden. Das ist vor allem problematisch wenn Datenstrukturen auf einmal wirklich einen größeren Kreis bilden (also Instanz 1 von Klasse A zeigt auf Instanz von Klasse B, die auf Instanz 2 von Klasse A die auf Instanz 2 von Klasse B zeigt die dann wiederum auf Instanz 1 von A zeigt). Wenn so eine Struktur dann serialisiert werden muss (also z.B. um sie in eine Datenbank oder in eine Datei zu schreiben oder übers Netzwerk verschickt werden muss), dann läuft man gerne in eine Endlosschleife.

himitsu 7. Mai 2021 06:56

AW: Delphi vs. JAVA , Class Design
 
Nja, so ganz nichtmachen geht auch nicht.

Auch Patent-Child (Liste/Tree + ListenObjekt), wenn man da im Child auf den Parent referenzieren möchte, dann passiert sowas halt.

Phoenix 7. Mai 2021 07:06

AW: Delphi vs. JAVA , Class Design
 
Zitat:

Zitat von himitsu (Beitrag 1488788)
Nja, so ganz nichtmachen geht auch nicht.

Das hab ich ja auch nicht gesagt :wink:
Halt einfach wohldosiert einsetzen und sich der möglichen Probleme immer bewusst sein. :thumb:


Alle Zeitangaben in WEZ +1. Es ist jetzt 00:32 Uhr.

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