Vererbung Frage



  • HAllo Leute ich habe 2 Fragen, die erste wohl eher trivial, ist mir nur momentan nicht klar, und die 2. bezieht sich auf mein Lehrbuch, das eigentlich die msdn Referenz & Programmierhandbuch ist.

    1.)

    class Test_1{
    
    }...
    

    vs.:

    public class Test_1{
    
    }...
    

    Ich kann beide Klassen gleich benutzen in meinem Code, was macht der public Zusatz bei der Klasse hier aus ??

    2.) Im MSDN steht :

    Wenn in einer Basisklasse eine Methode als virtuell deklariert wird, kann die Methode in einer abgeleiteten Klasse mit einer eigenen Implementierung überschrieben werden.

    Folgender Code funktioniert bei mir aber einwandfrei ohne den virtuell Zusatz, noch das ich override einfügen müsste...

    class Test {
    
            public  void greet() {
    
                Console.WriteLine("Greetings from Base Class");
            }         
        } 
    
         class TXT : Test {
    
            public  void greet() {
    
                Console.WriteLine("Greetings from inheritated Class");
            }
        }
    
    static void Main(string[] args) {
    
                Test v1 = new Test();
    
                v1.greet();
    
                TXT v2 = new TXT();
    
                v2.greet();
    }
    

    Ausgabe :
    Greetings from Base Class
    Greeting from interitated Class

    => Hab ich das falsch Verstanden ? Ich dachte ich kann die geerbte Methode greet () nur überschreiben wenn sie virtual ist und in der abgeleiteten Kalsse mit override gekennzeichnet ist... ?



  • public sowie protected, internal und private sind sog. Access Modifiers, d.h. diese geben die Sichtbarkeit der Klasse (bzw. Methode, Eigenschaften und Felder) an. Bei Klassen ist "internal" der Standard.
    Dies wird dann wichtig, wenn du Klassen aus anderen Assemblies (DLLs) heraus aufrufen willst, dann ist "public" davor zu setzen.

    Zu 2.: So hast du zwei gleichnamige Methoden erzeugt, welche völlig unabhängig voneinander sind.

    Bei Vererbung geht es darum, das Verhalten auszutauschen.
    Probiere daher mal:

    Test v1 = new Test();
    
    v1.greet();
    
    Test v2 = new TXT(); // <-- hier die Änderung
    
    v2.greet();
    

    Du solltest jetzt beides mal "base class" ausgegeben bekommen.

    Und nun ändere mal die Methoden auf virtual bzw. override und lasse den Code nochmal durchlaufen.



  • Danke, kapiert.



  • Bzw. kapiert aber ich bekomme mit dem Beispiel Compilerfehler CS0266 :
    Der Typ "Typ1" kann nicht implizit in "Typ2" konvertiert werden.Es ist bereits eine explizite Konvertierung vorhanden.

    Die Lösung mit dem Casten laut MSDN finde ich jetzt doch komisch, bzw. ist das ja nicht wirklich eine Lösung ?

    Test v1 = new Test();
    
    v1.greet();
    
    TXT v2 = new Test(); // Konvertierungsfehler
    

    Aber genau darum vererbe ich doch , bzw. sollte das doch funktionieren oder scheitert das ganze jetzt an meinem Klassenaufbau ?



  • Umgekehrt geht natürlich nicht.
    Wenn Vogel von Tier erbt, dann ist natürlich nicht jedes Tier ein Vogel.

    Einen sog. "Upcast" sollte man, so gut es geht, vermeiden.



  • Th69 schrieb:

    Einen sog. "Upcast" sollte man, so gut es geht, vermeiden.

    Ich mach die aber dauernd.



  • Ok... dann mal mit dem Tier Beispiel

    class Tier {}
    
    class Vogel : Tier {}   // Vogel erbt von Tier , ist ja auch ein Tier
    
    ....
    main{
    
    Tier animal1 = new Tier();   // ein neues Tier
    
    Tier animal2 = new Vogel()  ; // neues Tier ein Vogel, passt auch,  Tier kann ein Vogel sein
    
    Vogel animal3 = new Tier()   //Konvertierungsfehler, Vogel ist aber eigentlich auch ein Tier... ?
    

    Ich hab mir schon mehrere Bspl. angesehen und auch im Lehrbuch gelesen, aber irgendwie fess ich das nicht ganz mit dem Vererbungs, bzw. abgeleiteten Klassen zeugs...



  • @volkard: OK, da habe ich mich wohl zwischen up und down vertan, meinte "Downcasts" (wie in downcast and upcast) (auch wenn für mich die Basisklasse unten ist und die davon erbende Klasse weiter oben - und nicht umgekehrt, aber was soll's? ;-).

    @inheritance:
    Ein Vogel kann aber nicht einfach aus einem Tier erzeugt werden, denn der Vogel hat ja evtl. mehr Member (und Methoden).
    Sonst könnte man ja schreiben:

    Tier animal = new Fisch(); // neues Tier ein Fisch, passt auch, Tier kann ein Fisch sein
    
    Vogel vogel = animal;
    

    Und dann wäre plötzlich ein Vogel ein Fisch! Und deshalb gibt es den Kompilierungsfehler!

    Dies ist besonders dann interessant, wenn man eine Liste von Basisobjekten (Tieren) hat: List<Tier>. Dann kann man über diese Liste iterieren und direkt auf dessen Basisklasseneigenschaften- und -methoden zugreifen (unabhängig davon, ob das konkrete Objekt nun ein Fisch, Vogel, oder ... ist).

    Nur wenn man dann konkrete Eigenschaften und/oder Methoden der erbenden Klasse (d.h. Fisch oder Vogel) aufrufen möchte, muß man casten. Passend dazu: Gewusst wie: Sichere Umwandlung mit den Operatoren "as" und "is" (ebenfalls mit dem Animal-Beispiel ;-).



  • Und dann wäre plötzlich ein Vogel ein Fisch!

    Jetzt ist das Licht angeganen!!1 👍 👍 👍 . (Evtl. eine fliegender Fisch 🙂 ) . Danke nochmal


Anmelden zum Antworten