Delphi-PRAXiS
Seite 2 von 3     12 3      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Constructor in der Vererbung (https://www.delphipraxis.net/181182-constructor-der-vererbung.html)

himitsu 23. Jul 2014 11:12

AW: Constructor in der Vererbung
 
Nicht ganz. Innerhalb einer Unit ist Private wie Public, weswegen auch das Strict Private erfunden wurde.

Uwe Raabe 23. Jul 2014 11:58

AW: Constructor in der Vererbung
 
Zitat:

Zitat von himitsu (Beitrag 1266410)
Nicht ganz. Innerhalb einer Unit ist Private wie Public, weswegen auch das Strict Private erfunden wurde.

Das schränkt Stevie's Empfehlung ja nicht ein.

Man kann das Verhalten von Private innerhalb einer Unit auch als Designfehler betrachten, der aus Kompatibilitätsgründen nicht direkt behoben werden konnte. Die Einführung von Strict Private als echtes Private war sozusagen die Konsequenz.

Wenn ich sehe, daß auf Private Member von außerhalb der eigenen Klasse zugegriffen wird, ist das eigentlich ein Fall für ein Refactoring. Leider ist das auch im Delphi-eigenen Source viel zu weit verbreitet.

Stevie 23. Jul 2014 12:19

AW: Constructor in der Vererbung
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1266412)
Man kann das Verhalten von Private innerhalb einer Unit auch als Designfehler betrachten, der aus Kompatibilitätsgründen nicht direkt behoben werden konnte. Die Einführung von Strict Private als echtes Private war sozusagen die Konsequenz.

Wenn ich sehe, daß auf Private Member von außerhalb der eigenen Klasse zugegriffen wird, ist das eigentlich ein Fall für ein Refactoring. Leider ist das auch im Delphi-eigenen Source viel zu weit verbreitet.

Da stimme ich bedingt zu. Es gibt teilweise schon Dinge, die innerhalb der Bibliothek selber zugreifbar sein müssen aber nicht für einen Benutzer dieser Bibliothek. Dazu gibt es zum Beispiel in C# die Sichtbarkeit internal.
In Delphi bleibt einem da leider nichts anderes übrig, als die beteiligten Klassen in dieselbe Unit zu packen und dort auf private oder protected Member zuzugreifen.

Mikkey 23. Jul 2014 12:39

AW: Constructor in der Vererbung
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1266412)
Man kann das Verhalten von Private innerhalb einer Unit auch als Designfehler betrachten, der aus Kompatibilitätsgründen nicht direkt behoben werden konnte.

Man kann nicht nur, man muss, denn das Verhalten vom "protected" ist in dieser Hinsicht genau dasselbe (zumindest im Delphi7):

Delphi-Quellcode:
type
  TForm1 = class(TForm)
  protected
    Procedure ProtectedProc();
  end;
var
  Form1: TForm1;

implementation

Procedure TForm1.ProtectedProc();
begin
end;

procedure Main();
begin
  Form1.ProtectedProc(); // kein Fehler !!!
end;
Edit - Anmerkung: Ich habe nur das von der IDE vorgefertigte Projekt ergänzt und gekürzt. Das es als Programm so nicht laufen kann, ist mir klar.

DeddyH 23. Jul 2014 12:45

AW: Constructor in der Vererbung
 
Das stimmt nicht ganz. Abgeleitete Klassen können auf private Felder/Methoden nur dann zugreifen, wenn sie in derselben Unit deklariert sind. Für protected Members gilt das nicht.

Der schöne Günther 23. Jul 2014 12:49

AW: Constructor in der Vererbung
 
Dann wären da noch Tricksereien mit Klassenhelfern und Interposer-Klassen (die ja grade wegen dem "oder selbe Unit"-Prinzip funktionieren).

Die Sichtbarkeitsmodifikatoren einmal überarbeiten- Das ist mein #1-Feature was mir in der Sprache Delphi/Object Pascal am meisten fehlt. Bitte gebt mir vernünftige Namespaces und einen Sichtbarkeitsmodifikator der dem "internal" in C# bzw dem "Default" in Java entspricht. Und damit bitte gleich ein
Delphi-Quellcode:
uses System.Generics.*
8-)

C++ hat zwar auch nur public, private und protected aber wenigstens noch vernünftige Namespaces und im Notfall ein "using". In Pascal gewinnt einfach nur der letzte Import- Und man bekommt noch nicht einmal eine Compilerwarnung wenn eine Unit Symbole einer anderen einfach verdeckt. Das finde ich schon ziemlich hart.

Captnemo 23. Jul 2014 17:22

AW: Constructor in der Vererbung
 
Ich muss das ursprüngliche Thema noch mal aufgreifen, da ich noch ein paar Probleme habe, die ich mir nicht erklären kann.

Hier noch mal meine Klassen:
Delphi-Quellcode:
type
  TBefehl = class(TObject)
  private
    fGuid: AnsiString;
    fZeilen: Integer;
    fZeilenText: AnsiString;
    fFirstRow: Integer;
    fLastRow: Integer;
    fElseRow: Integer;
    FBlockGuid: AnsiString;
    FIsInBlock: Boolean;
    FIsInElse: Boolean;
  published
    property Zeilen: Integer read fZeilen write fZeilen;
    property ZeilenText: AnsiString read fZeilenText write fZeilenText;
    property FirstRow: Integer read fFirstRow write fFirstRow;
    property LastRow: Integer read fLastRow write fLastRow;
    property ElseRow: Integer read fElseRow write fElseRow;
    property IsInBlock: Boolean read FIsInBlock write FIsInBlock;
    property IsInElse: Boolean read FIsInElse write FIsInElse;
    property GUID: AnsiString read fGuid write fGuid;
    property BlockGuid: AnsiString read FBlockGuid write FBlockGuid;
  public
    constructor Create;
    procedure WriteBefehlToStream(Stream: TStream);
    procedure ReadBefehlFromStream(Stream: TStream);
  end;

type
  TECHO = class(TBefehl)
  private
    fOn: Boolean;
    fOff: Boolean;
    fAt: Boolean;
    fText: AnsiString;
    procedure SetRow(Row: Integer);
    function GetRow: Integer;
    procedure SetIsInBlock(Value: Boolean);
    function GetIsInBlock: Boolean;
    procedure SetIsInElse(Value: Boolean);
    function GetIsInElse: Boolean;
    procedure SetBlockGuid(Value: Ansistring);
    function GetBlockGuid: Ansistring;
  public
    procedure BuildZeilenText;
    procedure WriteToStream(Stream: TStream);
    procedure ReadFromStream(Stream: TStream);
  published
    property IsOn: Boolean read fOn write fOn;
    property IsOff: Boolean read fOff write fOff;
    property IsAt: Boolean read fAt write fAt;
    property Text: AnsiString read fText write fText;
    property Row: Integer read GetRow write SetRow;
    property localIsInBlock: Boolean read GetIsInBlock write SetIsInBlock;
    property localIsInElse: Boolean read GetIsInElse write SetIsInElse;
    property localBlockGuid: AnsiString read GetBlockGuid write SetBlockGuid;
  end;
Die Funktionen dazu
Delphi-Quellcode:
procedure TECHO.SetRow(Row: Integer);
begin
  fFirstRow:=Row;
  fLastRow:=Row;
  fElseRow:=-1;
  fIsInBlock:=False;
  fIsInElse:=False;
  fBlockGuid:='';
end;

function TECHO.GetRow: Integer;
begin
  Result:=fFirstRow;
end;

procedure TECHO.SetIsInBlock(Value: Boolean);
begin
  self.FIsInBlock:=Value;
end;

function TECHO.GetIsInBlock: Boolean;
begin
  Result:=Self.FIsInBlock;
end;

procedure TECHO.SetIsInElse(Value: Boolean);
begin
  self.FIsInElse:=Value;
end;

function TECHO.GetIsInElse: Boolean;
begin
  Result:=self.FIsInElse;
end;

procedure TECHO.SetBlockGuid(Value: AnsiString);
begin
  self.FBlockGuid:=Value;
end;

function TECHO.GetBlockGuid: AnsiString;
begin
  Result:=self.FBlockGuid;
end;

procedure TECHO.BuildZeilenText;
begin
  if (Self.fOn and not Self.fOff) then
    Self.ZeilenText:='ECHO On' else
  if (not Self.fOn and Self.fOff) then
    Self.ZeilenText:='ECHO Off' else
  if (not Self.fOn and not Self.fOff) then
    Self.ZeilenText:='ECHO '+self.fText;
  if self.fAt then
    Self.ZeilenText:='@'+Self.ZeilenText;
  self.Zeilen:=1;
end;
in der Formunit geht's dann folgendermaßen:

Delphi-Quellcode:
    echo:=TECHO.Create;
    echo.IsOn:=frm_echo.rb_echoon.Checked;
    echo.IsOff:=frm_echo.rb_echooff.Checked;
    echo.IsAt:=frm_echo.chk_at.Checked;
    echo.Text:=frm_echo.edt_eigenerText.Text;
    echo.BuildZeilenText;
    if (chk_anfuegen.Checked) or (lst_batch.Items.Count=0) then begin
      BefehlsListe.Add(echo);
      ActRow:=BefehlsListe.Count-1;
    end else begin
      begin
      echo.localIsInBlock:=InBlock;
      echo.localIsInElse:=InElse;
      echo.localBlockGuid:=Blockguid;
      BefehlsListe.Insert(IndexOfBefehlGuid(BefehlguidListe[ActRow]), echo);
BefehlsList ist eine TObjectList.

Nun mein Problem:

Bis zum "BefehlsListe.Insert" funktioniert alles. D.h. alle Properties werden wie gewünscht gesetzt, das habe ich im Debugger kontrolliert.

Wenn ich mir nach dem Insert mein Object "echo" im Debugger ansehe, dann die die Properties "IsInBlock, IsInElse und Blockguid" immer auf False bzw '' , egal was ich vorher gesetzt habe. Ich komme aber nicht dahinter, warum das so ist. Interessanterweise ist der Zeilentext, der ja auch in der Klasse TBefehl deklariert ist, noch dem Insert noch vorhanden.

Bitte nicht über den Sinn der Funktionen oder Propertynamen diskutieren, ist eh nur ein Spass- und Übungsprojekt.

Uwe Raabe 23. Jul 2014 17:37

AW: Constructor in der Vererbung
 
Wird vielleicht SetRow aufgerufen?

Captnemo 23. Jul 2014 17:52

AW: Constructor in der Vererbung
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1266465)
Wird vielleicht SetRow aufgerufen?

Daaaaaaaaankeee.
(Typisch Uwe...kurz und knapp und immer auf den Punkt;-) )

Das sucht man Stundenlang, und hat's vor Augen.....(kopfschütteln).
Hab schon in den Tisch gebissen, weil ich immer nach einem Fehler in der Definition gesucht habe.
Ich mach besser mal Schluss für heute :-D

Der schöne Günther 23. Jul 2014 18:13

AW: Constructor in der Vererbung
 
Am Rande: Dein BefehlsList ist noch die alte TObjectList und nicht die aus System.Generics.Collections, oder?

Auch: Kannst du nicht im Debugger weiter hineingehen (F7), was darin jetzt mit deinem Objekt angestellt wird?

Und: Ich habe jetzt nicht lange darüber gebrütet, aber GUID, Methoden zum Index suchen, usw- Hast du dir mal das TDictionary angeschaut?


Alle Zeitangaben in WEZ +1. Es ist jetzt 19:23 Uhr.
Seite 2 von 3     12 3      

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