Delphi-PRAXiS
Seite 1 von 4  1 23     Letzte »    

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Warum kann man Vererbung verhindern (csInheritable)? (https://www.delphipraxis.net/75763-warum-kann-man-vererbung-verhindern-csinheritable.html)

MaBuSE 24. Aug 2006 17:11


Warum kann man Vererbung verhindern (csInheritable)?
 
Hallo,

ich habe mal eine grundsätzliche Frage:

Warum ist es möglich zu verhindern, dass ein Formular abgeleitet werden kann?

Aber nun das Ganze im Detail (am Beisp. von D7):
  • Wir erstellen eine neue Anwendung.
  • Auf das Form1 legen wir einen TButton mit dem onClick Ereignis:
    Delphi-Quellcode:
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      Close;
    end;
  • Dann speichern wie das Projekt ab.
  • Im Menüpunkt "Datei -> Neu... -> Weitere..." wechseln wir zu dem "Project1" Tab und wählen das Form1 aus.
  • die IDE zeigt nun ein Formular Form2 an dass vom Typ TForm2 = class(TForm1) ist:
    Delphi-Quellcode:
    unit Unit2;

    interface

    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs;

    type
      TForm2 = class(TForm1)
      private
        { Private-Deklarationen }
      public
        { Public-Deklarationen }
      end;

    var
      Form2: TForm2;

    implementation

    {$R *.dfm}

    end.
  • Nun ändern wir die Peoject1.dpr wie folgt ab:
    Delphi-Quellcode:
    program Project1;

    uses
      Forms,
      Unit1 in 'Unit1.pas' {Form1},
      Unit2 in 'Unit2.pas' {Form2};

    {$R *.res}

    begin
      Application.Initialize;
    //  Application.CreateForm(TForm1, Form1); // <- Diese Zeile auskommentieren
      Application.CreateForm(TForm2, Form2);
      Application.Run;
    end.
  • Dann starten wir das Programm.
    Es ist nun ein Form2 zu sehen mit dem Close Button.
So weit so gut.

Mit dieser Technik kann man sich Formulare erstellen, die eine gewisse Basisfunktionalität haben.
Diese können dann in den Anwendungen verwendet werden, ohne das man alles noch mal neu programmieren muß.
Änderungen an den Basisformularen sind auch sofort in allen abgeleiteten Formularen (nach einem Recompile der Programme) verfügbar.

Super !!!
Genau das will ich haben.

Aber:

Wenn man nun eine Komponente auf das TForm1 legt, die in ComponentState kein csInheritable hat, dann kann ich das Formular nicht mehr vererben.

Es gibt 3 Komponenten bei denen das der Fall ist.
  • TActionManager (bzw. TCustomActionManager)
  • TNotebook
  • TTabbedNotebook
Man kann auch sehr leicht eigene Komponenten schreiben, die das Vererben verhindern:
Delphi-Quellcode:
unit VererbungIstDoof;

interface

uses
  SysUtils, Classes;

type
  TVererbungIstDoof = class(TComponent)
  private
    { Private-Deklarationen }
  protected
    { Protected-Deklarationen }
  public
    { Public-Deklarationen }
    constructor Create(AOwner: TComponent); override;
  published
    { Published-Deklarationen }
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('Beispiele', [TVererbungIstDoof]);
end;

{ TVererbungIstDoof }

constructor TVererbungIstDoof.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  Exclude(FComponentStyle, csInheritable);
end;

end.
Die Hilfe von Delphi 7 schreibt dazu
csInheritable
Abgeleitete Formulartypen können von der Komponente erben. Wenn bei einer der Komponenten eines Formulars das Flag csInheritable nicht gesetzt ist, kann das Formular nicht als Vorfahr für andere Formulare verwendet werden.


Meine Frage ist nun: "Warum kann man das Vererben verhindern?"

bzw. Warum ist das bei den 3 Komponenten der Fall. Sind die etwa nicht "vererbungssicher"?

Weiß das jemand hier im Forum?

Für eine Antwort wäre ich dankbar.

ps: Auch für Vorschläge, wie man trotzdem Formulare mit einem TActionManager vererben kann. ;-)

sakura 24. Aug 2006 17:16

Re: Warum kann man Vererbung verhindern (csInheritable)?
 
Zitat:

Zitat von MaBuSE
ps: Auch für Vorschläge, wie man trotzdem Formulare mit einem TActionManager vererben kann. ;-)

Zumindest einen Workaround dafür habe ich: DataModule ;)

Den Rest muss ich mir mal durch den Kopf gehen lassen.

...:cat:...

MaBuSE 24. Aug 2006 17:21

Re: Warum kann man Vererbung verhindern (csInheritable)?
 
Zitat:

Zitat von sakura
Den Rest muss ich mir mal durch den Kopf gehen lassen.

Mir geht das auch schon eine Weile durch den Kopf. (In der DP ist dazu nix zu finden).

Ich dreh mich schon so lange im Kreis, das es mir langsam schwindlig wird :spin2:

DatenModul bringt mir in dem Fall nicht viel. Wäre aber OT das genau zu erklären.

Flocke 24. Aug 2006 17:46

Re: Warum kann man Vererbung verhindern (csInheritable)?
 
Nur als Hinweis: es gibt dazu schon eine Anfrage im QC (QC#5853).

MaBuSE 24. Aug 2006 17:49

Re: Warum kann man Vererbung verhindern (csInheritable)?
 
Zitat:

Zitat von Flocke
Nur als Hinweis: es gibt dazu schon eine Anfrage im QC (QC#5853).

Danke, aber das bringt mich auch nicht wirklich weiter.
Das es von TCustomActionManager explizit entfernt wird wusste ich ja schon.
Aber beruigend zu wissen, dass ich nicht der Einzige bin, der solche Probleme hat.

Der_Unwissende 24. Aug 2006 18:00

Re: Warum kann man Vererbung verhindern (csInheritable)?
 
Zitat:

Zitat von MaBuSE
ich habe mal eine grundsätzliche Frage:

Warum ist es möglich zu verhindern, dass ein Formular abgeleitet werden kann?

Hi,
ist eigentlich eine wirklich interessante Frage. Hab noch gar nicht drüber nachgedacht, dass Delphi ja auch diese Funktionalität bietet. An sich gibt es ja auch in anderen Sprachen die Möglichkeit eine Klasse nicht erweiterbar zu deklarieren. In Java wäre eine solche Klasse dann mit dem Schlüsselwort final versehen.
Ich weiß nicht warum Delphi in diesen 3 von dir genannten Fällen keine Vererbung zulässt, aber die sehr generelle Motivation sollte hier eigentlich weniger gegeben sein.
So weit ich weiß ist die Motivation eigentlich, dass man Methoden statisch bindet, wenn es keine weiteren Ableitungen gibt. Dies ist in Delphi automatisch bei jeder Methode der Fall, die nicht mit virtual oder dynamic versehen wird. Sollten jetzt also Methoden "mitgeschleppt" werden, die an dieser Stelle noch nicht statisch sind, würde dies so geändert werden. Es entfällt ein Overhead (der zu vernachlässigen sein sollte).
Es ist (imo) häufig mal ärgerlich, wenn man eine Klasse findet und die nicht weiter abgeleitet werden kann. Wie gesagt, ist ein wenig perfomanter (vielleicht stammt es auch aus einer Zeit als es mit der Perfomance noch nicht so weit her war). Heute wird es hauptsächlich für z.B. private Klassen eingesetzt. Hier kann der Kompiler ein wenig mehr optimieren.
An sonnsten ist es vielleicht noch ein gutes Mittel um zu verhindern, dass jmd. ein Komponente die man verkauft einfach ableitet und nach eigenen Bedürfnissen anpasst. Hat jmd. die dcu stünde es ihm sonst (virtuelle Mehtoden vorrausgesetzt) frei dies zu tun, was man natürlich wieder als Leistung verkaufen könnte...

Bin mir allerdings null sicher, ob eine dieser Motivationen auch bei Delphi hinter der Möglichkeit steckt (denke fast eher nicht!).

Gruß Der Unwissende

Jelly 24. Aug 2006 18:01

Re: Warum kann man Vererbung verhindern (csInheritable)?
 
Also ich vermute, dass es verschiedene Komponenten gibt, die nur einmal pro Anwendung erlaubt sind, oder genutzt werden sollen (XPManifest, TDatabase usw.).

Grad bei TDatabase darf pro Anwendung nur eine TDatabase pro Datenbank definiert sein. Wenn Du jetzt aber von einer Form erbst, die eine TDatabase implementiert, so hast du zwangsläufig 2 identische Verbindungen.

Dieser Artikel bestätigt auch meinen Verdacht... Mann, bin ich gut :mrgreen:

jbg 24. Aug 2006 18:17

Re: Warum kann man Vererbung verhindern (csInheritable)?
 
Zitat:

Zitat von Der_Unwissende
Bin mir allerdings null sicher, ob eine dieser Motivationen auch bei Delphi hinter der Möglichkeit steckt (denke fast eher nicht!)

In einem Interview verrät Anders Hejlsberg seine Gründe. (zwar für C#, aber das sollte bei ihm wohl auch bei Delphi gelten)

sakura 24. Aug 2006 18:54

Re: Warum kann man Vererbung verhindern (csInheritable)?
 
Zitat:

Zitat von jbg
In einem Interview verrät Anders Hejlsberg seine Gründe. (zwar für C#, aber das sollte bei ihm wohl auch bei Delphi gelten)

Da geht es um virtuelle Methoden (default ja vs. nein). Mark geht es aber um was anderes ;)

...:cat:...

jbg 24. Aug 2006 19:10

Re: Warum kann man Vererbung verhindern (csInheritable)?
 
Zitat:

Zitat von sakura
Mark geht es aber um was anderes

Scheint wohl nicht meine Woche zu sein. :shock:


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:11 Uhr.
Seite 1 von 4  1 23     Letzte »    

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