Autor Beitrag
r0xta
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 25



BeitragVerfasst: Do 08.04.10 15:03 
Hallo zusammen,

bin im OpenBook unter 2.4 über Polymorphismus gestolpert.
openbook.galileocomp...csharp/kap01.htm#t24

Das Prinzip der Vererbung ist mir soweit klar.

Den Polymorphismus hab ich so verstanden: Eine virtuelle Funktion ist eine Funktion die erst mal nackt ist, die nicht implementiert wurde, wo nichts drin steht. Aus einer anderen Klasse (geht es auch innerhalb einer Klasse??) kann ich jetzt diese Funktion mit einer oder mehreren anderen Funktionen (override SelberFunktionsname) überschreiben.

Was bei mir etwas für Verwirrung gesorgt hat war folgendes:
Zitat:
...einen Verweis...erstellen..., und der Compiler schreibt Code zum Aufrufen der geeigneten Funktionsversion zur Laufzeit.


Was bedeutet "Code zum Aufrufen der geeigneten Funktionsversion zur Laufzeit"?
Schreibt das Programm/der Compiler da irgendwo im Hintergrund nen Quelltext der regelt zu welchem Zeitpunkt die Funktion überschrieben werden soll (evtl. um gleichzeitiges Zugreifen zu verhindern?) oder bedeutet das dass einfach nur beim entsprechenden Aufruf (zur Laufzeit) der Quelltext in die virtuelle Funktion geschrieben wird?
norman2306
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 222
Erhaltene Danke: 16

Win XP, Win 7 64-Bit
C# 4.0 (VS2010)
BeitragVerfasst: Do 08.04.10 15:49 
Zitat:
Eine virtuelle Funktion ist eine Funktion die erst mal nackt ist, die nicht implementiert wurde


ich weiß ja nicht von welcher Sprache du redest, aber das wäre die umschreibung für 'abstract'. Eine virtuelle Methode funktioniert etwas anders. Wird die virtuelle Methode von einer abgeleiteten Klasse überschrieben, so wir stets die überschriebene Methode des zur Laufzeit am meisten abgeleiteten Objekt aufgerufen. Das ist auch mit dem Satz so in etwa gemeint.

Bsp:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
public class A
{
    public virtual void DoSomething(){MessageBox.Show("Class A Call");
}

public class B : A
{
    public overide void DoSomething(){MessageBox.Show("Class B Call");
}


Und nun der Aufruf:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
A a as A;
a.DoSomething();

//Result:

//"Class B Call"
r0xta Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 25



BeitragVerfasst: Do 08.04.10 16:19 
ok... abstract MUSS also leer sein, virtuell kann leer, aber auch implementiert sein?

wenn virtuell jetzt implementiert ist, und die dazugehörige override Methode wurde einmal ausgeführt, wird die virtuelle Methode für immer hinfällig?

oder muss die override Methode gar nicht explizit aufgerufen werden sondern sie überschreibt beim kompilieren automatisch? ich seh nämlich nicht den Aufruf der override-Methode in deinem Beispiel. Aber dann wäre ein implementieren der virtual-Methode überflüssig... Oder steh ich grad ma wieda ganz dick aufm Schlauch?
norman2306
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 222
Erhaltene Danke: 16

Win XP, Win 7 64-Bit
C# 4.0 (VS2010)
BeitragVerfasst: Fr 09.04.10 08:44 
Ich verstehe die Frage nicht so hundert prozentig, aber ich versuche es nochmal. Und da Code mehr als tausend Worte sagt :)

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
public class A
{    
   public virtual void DoSomething(){MessageBox.Show("Class A Call");
}

public class B : A
{    
    public overide void DoSomething(){MessageBox.Show("Class B Call");
}

public class C: A
{
  //C erbt einfach mal nur ohne einen Override von new zu machen
}

public class D: A
{
   public overide void DoSomething(){MessageBox.Show("Class D Call");
}


Zitat:
wenn virtuell jetzt implementiert ist, und die dazugehörige override Methode wurde einmal ausgeführt, wird die virtuelle Methode für immer hinfällig?

Da war ein kleiner Fehler bei mir drin:)
Also korrekt muss es so lauten:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
B b = new B();
A a = b;

a.DoSomething(); // => Liefert "Class B Call", denn von der a zugewiesenen Variable aus gesehen ist B die am meisten abgeleitete Klasse in der aktuellen Runtime, die die DoSomething implementiert.


C c = new C();
A a = c;

a.Something(); // => Liefert "Class A Call", denn in der Vererbungslinie von c ist a die letzte Klasse, die DoSomething implementiert

D d = new D();
A a = d;

a.DoSomething(); // => Liefert "Class A Call", denn Class b kennzeichnet "DoSomething" mit dem "new" Schlüsselwort und unterbricht damit die Vererbungslinie



Zitat:
ok... abstract MUSS also leer sein, virtuell kann leer, aber auch implementiert sein?


Nein. Virtuell muss Text beinhalten. Und wenn es leere Klammern sind. Eine Funktion mit Rückgabewert muss immer auch ein "return" besitzen. Wirklich leer dürfen nur "abstracts" sein. Virtuel macht eine Aussage darüber, wie vererbt wird. "Abstract" ist eine Vererbungsbedingung.

Stellen wir uns mal vor, du bist bei einer Testamentseröffnung, und der Notar erklärt, du erbst eine Million Euro, wenn du machst, dass Schweine fliegen. Das ist ein "abstract", weil du in der Welt erst implementieren musst, dass Schweine fliegen.

Uns jetzt Stellen wir uns mal vor, du gehst zu deinen Eltern und bittest darum, dein Erbe vorzuziehen, weil du dringend ein neues Auto brauchst. Dafür versprichtst du ihnen, dass sie es mitbenutzen dürfen. Hier gibt es aber mehrere Möglichkeiten:
* du nutzt das alte Auto deiner Eltern mit
* du kaufst ein neues Auto und ihr teilt es euch (override)
* du verzichtest auf das Erbe und kaufst ein neues Auto und verwerst ihnen die Nutzung (new)

Das wäre virtuel vererbt.