Announcement

Collapse
No announcement yet.

Zugriff auf Methoden mit/ohne Typumwandlung

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Zugriff auf Methoden mit/ohne Typumwandlung

    Hallo!
    Wieso kann man auf Methoden in einer abgeleiteten Klasse, welche NICHT in der Basisklasse enthalten sind nur bedingt zugreifen? <br>
    Folgendes Problem: <br>

    --- Basisklasse --- <br>
    TBaseClass = class
    procedure MachIrgendWas; virtuel; <br>
    end; <br>
    <br>

    --- Abgeleitete Klasse --- <br>
    TMyClass = class(TBaseClass)
    procedure MachIrgendWas; override; <br>
    procedure NeueMethode; <br>
    end; <br>

    --- Hauptprogramm --- <br>
    TMainForm = class(TForm) <br>
    TheClass: TBaseClass; <br>
    TheClass2: array[0..1] of TBaseClass; <br>
    end; <br>

    procedure TMainForm.Create;<br>
    begin <br>
    TheClass := TMyClass.Create; <br>
    TheClass.NeueMethode; // Geht nicht, da NeueMethode nicht in TBaseClass <br>
    TMyClass(TheClass).NeueMethode; // Geht, da Typumwandlung !? <br>
    TheClass2[0] := TMyClass.Create; <br>
    TheClass2[0].NeueMethode; // Geht !
    end; <br>
    <br>
    Kann mir jemand erklären warum ??!! <br>
    Danke <br>
    <br>
    Terry <br>

  • #2
    Hallo,<br><br>
    das liegt wohl daran, dass "TheClass" die Methode "NeueMethode" ja nicht kennt. Siehe dazu mal in der OH unter "abstract" nach, das dürfte genau das sein.<br>Ich habe auch meinen Compiler mal "überreden" können, einen TButton, TEdit, TLabel, usw. als TSpeedbutton zu behandeln (!), ich weiß aber nicht warum das funktioniert.<br><br>

    HTH<br> S.Rasc

    Comment


    • #3
      <p>Hallo,<br>
      <br>
      Du machst da einen kleinen Denkfehler:<br>
      Laut Deinen Deklarationen ist TheClass vom Typ "TBaseClass". Also muss der Aufruf <b>TheClass:=TBaseClass.Create;</b> lauten. Wenn Du TheClass als "TMyClass" deklarierst, dann funktioniert auch Dein Beispiel.<br>
      <br>
      Gruß Thomas</p&gt

      Comment


      • #4
        Hallo !

        Das liegt an deinen Deklarationen...

        <B>TheClass</B> hast du als TBaseClass deklariert und
        <B>TheClass2</B> als ein array von TBaseClass.

        jetzt zu deinem Problem...

        als du <I>TheClass</I> mit TMyClass.Create instanziert hast, wurde ein Object des Typs <I>TMyClass</I> erzeugt, jedoch ist <I>TheClass</I> als <I>TBaseClass</I> deklariert, somit weiß die Variable <I>TheClass</I> nichts von der Methode <I>NeueMethode</I>. Diese Problem konntest du ja mit der Typumwandlung bewältigen.

        Bei <I>TheClass2</I> verhält sich das ein wenig anders.
        <I>TheClass2</I> ist ja ein array, das wiederum Object vom Typ <I>TBaseClass</I>, und somit auch alle von dieser Klasse abgeleiteten Klassen/Objecte aufnehmen kann. Wenn du jetzt eine Instanz von TMyClass erzeugst, wie du ja richtig mit <I>TheClass2[0]:= TMyClass.Create</I> gemacht hast, wird ein Zeiger vom Typ <I>TMyClass</I> erzeugt und instanziert. Deshalb kennt die "Variable" <I>TheClass2[0]</I> auch die Methode <I>NeueMethode</I>

        Ich hoffe das war nich zu umständlich erklärt und deine Frage ist beantwortet

        mfg Stefa

        Comment


        • #5
          Hallo TerryK,<br>
          Dein Problem liegt auf einer ganz anderen Ebene.<p>
          Was Du machen möchtest, nennt man polymorphes Interface. Du kannst Deine Variablen alle vom Typ TBaseClass deklarieren. Soweit ist Dein Beispiel korrekt.<br>
          Wenn Du aber auf die Methode <b>NeueMethode</b> zugreifen möchtest, musst Du eine Instanz der Klasse mit einem Zugriff auf <b>NeueMethode</b> erzeugen.

          TheClass := TMyClass.Create; //korrekt<br>
          ( TheClass as TMyClass).NeueMethode; // Geht, da Type angepasst wird<br>

          DieseDeklaration solltest Du vermeiden. Besser ist die darüber<br>
          TMyClass(TheClass).NeueMethode; // Geht, da Typumwandlung !?<br>

          Wende Polymorphie an!!!<br>
          TheClass2[0] := TMyClass.Create; <p>
          Funktioniert nicht weil derCompiler hier schon streikt, da TheClass2[0] vom Type TBaseClass ist.<br>
          TheClass2[0].NeueMethode; // Geht nicht<br>
          Schon besser<br>
          ( TheClass2[0] as TMyClass ).NeueMethode; // Geht ! end; <br>
          <br>
          Damit sollte es auch mit dem Nachbarn klappen.<p>
          Gruss<br>
          Fran

          Comment

          Working...
          X