Verständnisproblem Vererbung (CSharp) ?!

aggroman

Lt. Junior Grade
Registriert
Sep. 2008
Beiträge
449
Tagchen,

ich komme direkt zur Sache:

Per this greift ja ein Objekt auf die Elemente zu welche zu diesem gehören.
Nun hab ich folgendes Problem. Bekanntlich werden public Methoden und Variablen vererbt. Nun hab ich eine public Methode die per this auf ein privates Feld der Basisklasse zugreift, also:

class Basisklasse
{

int i = 10;

public void AufrufMethodeBasisklasse()
{
Console.WriteLine("Ausgabe : " + this.i);
}

}

class Subklasse : Basisklasse
{

public void AufrufMethodeSubklasse()
{
this.AufrufMethodeBasisklasse();
}

}


Soweit so gut. Nur müsste der Compiler an dieser Stelle nicht meckern weil die private Variable nicht geerbt wurde?

Bin für jede Meinung dankbar

Gruß
Roman
 
Du greifst ja nicht direkt auf das private Feld zu, sondern benutzt eine öffentliche Methode die auf das Feld zugreift. Das ist by-design, da sonst z. B. Kapselung nicht realisierbar wäre.
 
Was genau erbt die Subklasse. Erbt Sie die komplette Methodenstruktur oder nur einen Zeiger auf die Methodtable der Basisklasse? Weil an dieser Stelle wäre ohne einer Instanzbildung der Zugriff au die Methode der Basisklasse per this möglich und das ist mir noch nicht ganz klar ... :(
 
Doch, natürlich werden auch alle privaten Felder vererbt, nur kannst du eben in den Methoden der abgeleiteten Klasse nicht direkt darauf zugreifen. Der Zugriff über Methoden der Basisklasse ist aber natürlich möglich und gewollt. Die Instanzbildung erfolgt implizit, heißt, eine Instanz einer abgeleiteten Klasse ist auch immer eine vollständige Instanz der Basisklasse... Über

(Basisklasse)this

kannst du auch direkt auf Methoden der Basisklasse zugreifen, wenn diese in der abgeleiteten überladen wurden...


Grüße

Brainfart
 
Zuletzt bearbeitet:
Wie gesagt es geht mir primär darum, dass ich die geerbte Methode per this Aufrufe d.h. ich greife auf die Methode der Klasse zu, zu welcher die Instanz gebildet wurde (also das Objekt der Klasse Subklasse)

Mich interessiert vor allem wie die Methoden intern definiert werden, ob Subklasse eine Referenz auf die Methode der Basisklasse bekommt oder tatsächlich eine Kopie der Methode.

Edit:
Dann deutet alles darauf hin, dass lediglich die Referenzen vererbt werden welche auf die Methoden der Basisklasse zugreifen
 
Zuletzt bearbeitet:
Methoden müssen nicht kopiert werden, es genügt, wenn sie einmal Speicher verwenden ;)
Ich bin mir nicht sicher, wie die CLR das handhabt, aber in C++ besteht eine Instanz aus zwei Bereichen: Einer Method-Table, in der Referenzen auf die jwlg. gültigen Überladungen der Methoden liegen und einem Datenbereich, der die eigentlichen Datenfelder der Klasse speichert...
 
dann versteh ich den sinn von virtual methoden nicht ganz. Wenn ich doch ohnehin immer auf die Methode der Basisklasse per base zugreifen kann.
 
Virtuelle Methoden dienen genau dem umgekehrten Zweck: Über eine Referenz auf die Basisklasse, hinter der sich aber eigentlich eine abgeleitete verbirgt, auf die Methoden der abgeleiteten zuzugreifen, Stichwort Polymorphie:

Code:
class Fahrzeug
{
      public virtual void Fahre();
}

class Auto : Fahrzeug
{
     public override virtual void Fahre();
}

class Motorrad : Fahrzeug
{
  public override virtual void Fahre();
}

...

ArrayList<Fahrzeug> Garage = new ArrayList<Fahrzeug>;

Garage[0] = new Auto();
Garage[1] = new Motorrad();

foreach(Garage as Fahrzeug f)
      f.Fahre();
 
Zuletzt bearbeitet: (Methoden müssen natürlich virtuell sein)
@BrainFart:
Jetzt meinst du aber abstract, oder?! Virtuelle Methoden brauchen einen Methodenrumpf und geben nur an, dass sie prinzipiell überschreibbar sind. Abstrakte Methoden geben an, dass die Klasse nicht vollständig definiert ist und diese Methoden überschrieben werden müssen.
Bei der Notation reicht override aus, da steckt virtual implizit mit drin.

df
 
Naja, nein, eine Methode ist auch überschreibbar, wenn sie nicht als virtuell deklariert ist, nur wird dann beim Zugriff über eine Referenz auf die Basisklasse auch bei abgeleiteten Klassen die Methode der Basisklasse aufgerufen... Mit dem abstract hast du recht, eine abstrakte Methode ist eine virtuelle ohne Implementierung in der Basisklasse, das macht aber dann automatisch die gesamte Klasse abstrakt (sie muss auch als abstract deklariert werden) und damit nicht instantierbar... Im Beispiel oben fehlen natürlich die Methodenrümpfe, war nur zur Veranschaulichung gedacht...
 
aggroman schrieb:
Tagchen,

ich komme direkt zur Sache:

Per this greift ja ein Objekt auf die Elemente zu welche zu diesem gehören.
Nun hab ich folgendes Problem. Bekanntlich werden public Methoden und Variablen vererbt. Nun hab ich eine public Methode die per this auf ein privates Feld der Basisklasse zugreift, also:

class Basisklasse
{

int i = 10;

public void AufrufMethodeBasisklasse()
{
Console.WriteLine("Ausgabe : " + this.i);
}

}

class Subklasse : Basisklasse
{

public void AufrufMethodeSubklasse()
{
this.AufrufMethodeBasisklasse();
}

}


Soweit so gut. Nur müsste der Compiler an dieser Stelle nicht meckern weil die private Variable nicht geerbt wurde?

Bin für jede Meinung dankbar

Gruß
Roman

this.AufrufMethodeBasisklasse() ist wenn du die Methode Basisklasse.AufrufMethodeBasisklasse() aufrufen willst schlicht falsch.
Es muss hier base.AufrufMethodeBasisklasse() heißen.
 
BrainFart schrieb:
Naja, nein, eine Methode ist auch überschreibbar, wenn sie nicht als virtuell deklariert ist, nur wird dann beim Zugriff über eine Referenz auf die Basisklasse auch bei abgeleiteten Klassen die Methode der Basisklasse aufgerufen...
Das geht in C# nur wenn man die Methode in der Subklasse mit dem "new"-Schlüsselwort kennzeichnet.
Das nennt man dann aber auch nicht "override" sondern "hiding" oder "shadowing", da die Methode der Basisklasse eben nicht "überschrieben" sondern nur "überlagert" bzw. "versteckt" wird.
Gilt aber allgemein eher als schlechter Stil.

IceMatrix schrieb:
this.AufrufMethodeBasisklasse() ist wenn du die Methode Basisklasse.AufrufMethodeBasisklasse() aufrufen willst schlicht falsch.
Es muss hier base.AufrufMethodeBasisklasse() heißen.
Im konkreten Fall ist das egal, weil die Methode "AufrufMethodeBasisklasse" nicht "virtual" und somit auch nicht überschrieben ist. Wenn eine Methode in der Subklasse nicht überschreiben wurde ist der Aufruf "this.Methode" und "base.Methode" equivalent. Mit "base.Methode" ruft man hingegen immer die Methode der Basisklasse auf, auch wenn die Methode überschrieben wurde.
 
Zuletzt bearbeitet: (Erzänzung zum Beitrag von IceMatrix)
TheCadillacMan schrieb:
Im konkreten Fall ist das egal, weil die Methode "AufrufMethodeBasisklasse" nicht "virtual" und somit auch nicht überschrieben ist. Wenn eine Methode in der Subklasse nicht überschreiben wurde ist der Aufruf "this.Methode" und "base.Methode" equivalent. Mit "base.Methode" ruft man hingegen immer die Methode der Basisklasse auf, auch wenn die Methode überschrieben wurde.

du musst bei C# zwischen einfachem überschreiben und virtuellen methoden unterscheiden.
du kannst methoden der basisklasse wie auch in c++ _immer_ überschrieben, selbst wenn sie nicht virtuell sind.

in c# muss die über das new-keyword allerdings explizit gemacht werden, c++ macht es durch die gleiche methodensignatur implizit.

bei einer virtuellen methode heißt bei c# das keyword nicht new, sondern override.
 
IceMatrix schrieb:
du kannst methoden der basisklasse wie auch in c++ _immer_ überschrieben, selbst wenn sie nicht virtuell sind.
Wie bereits erwähnt heißt das dann aber nicht mehr "überschreiben" (engl. override) sondern "verdecken" (engl. name hiding, Quelle: C# Language Specification)
Umgangssprachlich hab ich auch schon mal den Begriff "shadowing" also "überschatten" gesehen, "hiding" ist aber der korrekte Begriff.
 
Zurück
Oben