Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Muss Sender immer TComponent sein? (https://www.delphipraxis.net/157697-muss-sender-immer-tcomponent-sein.html)

Jumpy 21. Jan 2011 11:30

Muss Sender immer TComponent sein?
 
Hallo,

ich hab eine Klasse TMSG (ohne Form), die Nachrichten-Strings sammelt und eine Klasse TViewMSG (mit Form), die Nachrichten anzeigt.

z.Zt. wird ein TViewMSG Object in TMSG erzeugt über:
Delphi-Quellcode:
fViewMSG:= TViewMSG.Create(nil);

Die Klasse bzw. das Form TViewMSG hat noch keine eigene OnCreate-Routine.

Nun möchte ich das aber so ändern, dass TViewMSG eine Referenz auf TMSG bekommt, indem sich zunächst der Aufruf in TMSG ändert zu:
Delphi-Quellcode:
fViewMSG:= TViewMSG.Create(self);


Gleichzeitig hab ich dann auch das OnCreate-Ereignis testweise in TViewMSG erzeugt:
Delphi-Quellcode:
procedure TViewMSG.FormCreate(Sender: TObject);
begin
  showmessage(Sender.ClassName);
  inherited Create(nil);
end;
Der Kompiler meckert aber schon bei fViewMSG:= TViewMSG.Create(self);
[Fehler] uMSG.pas(200): Inkompatible Typen: 'TComponent' und 'TMSG'

Daher die Frage, muss der Sender immer eine Komponente sein, oder was versteh ich da nicht?

Jumpy

DeddyH 21. Jan 2011 11:40

AW: Muss Sender immer TComponent sein?
 
Der Sender muss TObject sein (also eine beliebige Klasse), der Owner aber TComponent.

Jumpy 21. Jan 2011 11:49

AW: Muss Sender immer TComponent sein?
 
Muss ich dann beides übergeben? Wie?

fViewMSG:= TViewMSG.Create(self,nil);

Oder übergebe ich nur den Owner, der Sender wird dann automatischmitgeliefert?

-----
Edit:

Habs mal ausprobiert mit:
in TMSG: fViewMSG:= TViewMSG.Create(nil);

und in TViewMSG
Delphi-Quellcode:
procedure TViewMSG.FormCreate(Sender: TObject);
begin
  showmessage(Sender.ClassName);
  inherited Create(nil);
end;
Das gibt schonmal keine Fehlermeldung, aber als Sender wird mir nun TViewText angezeigt.
Wie krieg ich die aufrufende/erzeugende Klasse an die erzeugte Klasse?

DeddyH 21. Jan 2011 11:58

AW: Muss Sender immer TComponent sein?
 
Das "inherited Create" gehört nicht ins FormCreate, sondern in den Konstruktor. Zeig uns doch einmal die Deklaration der beiden Konstruktoren.

Jumpy 21. Jan 2011 12:49

AW: Muss Sender immer TComponent sein?
 
Hallo DeddyH,

deine Frage hat mir schon die Augen geöffnet. OnCreate ist ja nicht der Konstruktor (wie ich blöderweise dachte) sondern das Ereignis, das beim Aufruf des Konstruktors gefeuert wird.
Daher war der Sender bei mir oben auch das TViewMSG selbst.

Da ich keinen Konstruktor hatte, galt denk ich mal der der Mutterklasse TForm und der will halt gern einen Owner TComponent.

Hab das OnCreate gelöscht und folgenden Konstruktor gebaut:
Delphi-Quellcode:
constructor TViewMSG.Create(Sender: TObject);
begin
  if Sender is TComponent then inherited Create(TComponent(Sender))
  else inherited Create(nil);
  if Sender <> nil then showmessage(Sender.ClassName);
end;
Damit läuft es, wie es soll, aber es kommt die Warnung im Kompiler:
[Warnung] mViewMSG.pas(31): Methode 'Create' verbirgt virtuelle Methode vom Basistyp 'TCustomForm'

Ist das schlimm? Muss ich da noch irgendwo ein override oder so hinzufügen?

DeddyH 21. Jan 2011 12:57

AW: Muss Sender immer TComponent sein?
 
Zitat:

Zitat von Jumpy (Beitrag 1076351)
Ist das schlimm? Muss ich da noch irgendwo ein override oder so hinzufügen?

Richtig erkannt. Schreib im Interface-Teil einfach "override;" hinter die Konstruktor-Deklaration, dann sollte die Meldung verschwinden.

[edit] Halt! Geht so nicht, da Du ja keinen Owner, sondern einen Sender übergibst. [/edit]

[edit2] Wovon ist denn TViewMSG abgeleitet? TCustomForm? [/edit2]

Jumpy 21. Jan 2011 13:10

AW: Muss Sender immer TComponent sein?
 
Delphi-Quellcode:
type
  TViewMSG = class(TForm)
    ActionList1: TActionList;
    ToolBar1: TToolBar;
    ToolButton1: TToolButton;
    acClose: TAction;
    Memo1: TMemo;
    ToolButton2: TToolButton;
    acSenden: TAction;
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure acCloseExecute(Sender: TObject);
    procedure acSendenExecute(Sender: TObject);
  private
    { Private-Deklarationen }
    FText: string;
    function getComputerName: string;
    function getUserName: string;
    function getSubject: string;
    procedure SetInhalt(const Value: string);
  public
    { Public-Deklarationen }
    property Inhalt : string write SetInhalt;
    constructor Create(Sender: TObject);
  end;
Hier mal der Deklarationsteil. Ist TForm dasselbe wie TCustomForm?
Muss eine überschriebene (override) Funktion die selben Parameter haben, wie die orginale Funktion?
Im Gegensatz zu überladen, wo es ja immer andere Parameter sein müssen? OOP ist für mich noch sehr neu und theoretisch.

DeddyH 21. Jan 2011 14:13

AW: Muss Sender immer TComponent sein?
 
Zitat:

Zitat von Jumpy (Beitrag 1076364)
Muss eine überschriebene (override) Funktion die selben Parameter haben, wie die orginale Funktion?

Ja, Du kannst sie aber dann wieder überladen, um eigene Parameter definieren zu können. Eine andere Möglichkeit wäre reintroduce, welches ich selbst allerdings noch nicht benutzen musste. Damit kannst Du sagen "ich weiß, dass ich das Original verberge, aber ich will das bewusst so."

[edit] Was spricht denn dagegen, den geerbten Konstruktor einfach zu überschreiben? Entweder wird ein Owner übergeben oder eben nil, diese Verrenkungen kannst Du Dir ja dann sparen. [/edit]

Jumpy 21. Jan 2011 14:33

AW: Muss Sender immer TComponent sein?
 
Denke auch. Mach es jetzt so:
Delphi-Quellcode:
implementation
{$R *.dfm}

uses uMSG;

{TViewMSG}

var MSG:TMSG //Variable, in der (eine Referenz auf) die erzeugende Klasse gespeichert wird.

constructor TViewMSG.Create(Sender: TObject);
begin
  inherited Create(nil);
  if Sender is TMSG then MSG:=TMSG(Sender);
end;
Das der org. Konstruktor verdeckt ist sollte egal sein, da ich ihn ja mit inherited selber aufrufe und es im Fall des Konstruktors eh egal ist, da ich ja nicht sowas Typecasten oder heißt es Objectcasten würde wie TForm(TViewMSG).Create(nil).

shmia 21. Jan 2011 15:30

AW: Muss Sender immer TComponent sein?
 
Zitat:

Zitat von Jumpy (Beitrag 1076383)
Mach es jetzt so...

So wie du das machst, ist es überhaupt nicht gut. (um nicht zu sagen "total käse")
Viel besser wäre so:
Delphi-Quellcode:
type
  TViewMSG = class(TForm)
...
  private
    { Private-Deklarationen }
    FText: string;
    FMSG : TMSG;  // <====
...  
    procedure SetInhalt(const Value: string);
  public
    { Public-Deklarationen }
    property Inhalt : string read FText write SetInhalt;
    property MSG:TMSG read FMSG write FMSG;  // <====
  end;
Damit übergibst du dein Objekt einfach von Aussen als Property.


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:29 Uhr.
Seite 1 von 2  1 2      

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