schlechtes Beispiel für Vererbung?



  • Hallo Leute!

    Ich suche ein schlechtes Beispiel für Vererbung. In meinem Tutorial will ich nämlich zeigen, wie man es nicht macht.

    Es sollte ein allgemeingültige Beispiel sein - also zB mit Vögeln 🙂 und nicht speziell sein, wie zB 'nicht von value types erben'.

    Hat da jemand eine Idee?



  • Quadrat von Rechteck (wegen LSP-Verletzung)
    oder sowas wie Auto von Motor (has-a und is-a durcheinandergebracht)



  • Ich suche ein schlechtes Beispiel für Vererbung.[...]
    Es sollte ein allgemeingültige Beispiel sein - also zB mit Vögeln

    In welcher Hinsicht soll es ein schlechtes Beispiel sein? Hier ist z.B. ein klassisches LSP-Verletzungs-Problem:

    class Bird
    {
    public:
    ...
        // Post: altidude > 0
        virtual void fly();
    };
    
    class Ostrich : public Bird
    {
    public:
    ...
        void fly(); // Ups
    };
    

    Vielleicht auch mehr ein "Komposition vs. Vererbung"-Problem:

    class Engine {...};
    class Car : public Engine
    {
    ...
    };
    

    Oder ein "Container-of thing != Container-of anything":

    class BagOfFruit
    {
    public:
        void insert(Fruit& f);
        ...
    };
    
    class BagOfApple : public BagOfFruit
    {
    public:
        void insert(Apple& a)
        {
            BagOfFruit::insert(a);
        }
    };
    
    void f()
    {
        BagOfApple ba;
        Banana b;
        ba.insert(b); // ups
    }
    

    Oder ein klassisches "Vererbung ist zu statisch und unflexibel":

    class TextView {...};
    class ScrollableTextView : public TextView {...};
    class BorderedTextView : public TextView {...};
    ...
    

    Oder das klassische "Mythos der Employee-Klasse"-Problem.

    Auch die white-box- vs. black-box-reuse Problematik eignet sich. Oder vielleicht ein klassiches "implementation vs. interface Vererbung"-Problem.
    Ich denke ist gibt tausende Beispiele. Kommt alles sehr starkt auf den Kontext an, in dem du dich befindest.



  • Ok. Einmal mehr hat ein zwischenzeitliches Telefonat meine Antwort überflüssig gemacht 🙂



  • @Hume:

    Dein Beitrag ist sicher nicht sinnlos - du hast mir sehr geholfen.

    Bashar natürlich auch. Ich werde mir aus euren Beispielen mal was ausdenken...

    thx 👍



  • Ich habe die Vögel genommen.

    Was haltet ihr von folgender (richtiger) Lösung des 'Vogel'-Problems:
    Pseudo-UML Diagramm

    Kann man das so lassen, oder sollte man es anders lösen? (schließlich reicht es ja nicht zu sagen: man kann Pinguin nicht einfach von Vogel ableiten, weil er ja nicht fliegen kann)

    danke schonmal



  • Sollte die Funktion getName() nicht einen Rückgabewert != void haben?



  • jo, habs schnell ausgebessert.

    Aber im Prinzip geht es mir weniger um die Member sondern um die Beziehungen der Klassen untereinander.



  • Naja, und ist es nicht so, das die Pfeile zu der Basisklasse gehen?



  • ja, sorry.

    Mir geht es nicht um solche Kleinigkeiten - ich würde nur gerne wissen ob die Beziehungen so passen. Ich hab das UML Diagramm nur gemalt, damit ich es euch besser zeigen kann. Da ich UML nicht besonders mag, verwende ich es auch quasi nie. sorry



  • Da ich UML nicht besonders mag, verwende ich es auch quasi nie.

    Hast du denn ein besseres oder überhaupt irendein allgemeinverständliches anders Mittel um Klassenhirachien darzustellen.



  • Können wir bitte wieder auf meine Frage zurück kommen?

    Ich will hier nicht über UML diskutieren, sondern darüber wie man Vogel, Amsel, Strauss und Pinguin zueinander in Beziehung setzt.



  • Shade Of Mine schrieb:

    Ich will hier nicht über UML diskutieren, sondern darüber wie man Vogel, Amsel, Strauss und Pinguin zueinander in Beziehung setzt.

    ich finde, dass dies sehr stark von kontext und anwendungsfall abhängt, also was du damit machen willst



  • class fahrzeug
    {
    virtual void fahren()=0;
    }
    
    class car: public fahrzeug
    {
    void fahren(){...}
    }
    
    class boot :public fahrzeug
    {
    void fahren(){...}
    }
    
    class Amphibienfahrzeug:public car, public boot // Errr
    }
    }
    


  • Bashar schrieb:

    (wegen LSP-Verletzung)

    edit: es ist wahrscheinlich schon zu spät...
    Bedeutet das sowas wie: "Quadrat verhält sich anders als ein Rechteck"?
    Sodass folgender Code nicht mit Quadraten funktioniert:

    bool foo(const Rechteck& r)
    {
      r.setWidth(1);
      r.setHeight(2);
      /* ... */
      return r.getWidth() == r.getHeight() / 2;
    }
    

    Wofür steht LSP?



  • Liskov substitution principle



  • Danke. 🙂



  • xroads42 schrieb:

    class fahrzeug
    {
    virtual void fahren()=0;
    }
    
    class car: public fahrzeug
    {
    void fahren(){...}
    }
    
    class boot :public fahrzeug
    {
    void fahren(){...}
    }
    
    class Amphibienfahrzeug:public car, public boot // Errr
    }
    }
    
    class Amphibienfahrzeug:public car, public boot // alles ok
    {
    void fahren(){ /* choose */ }
    }
    

    ist (meines wissens nach) eh nur mehrdeutig, wenn fahren auch aufgerufen wird.

    gruß
    cellar's child



  • wieso?
    ist doch alles in butter:
    vorraussetzung:

    virtual void fahren()
    


  • @c++profi:

    und welches fahren wird jetzt aufgerufen? Das von boot oder das von car?

    MfG Jester


Anmelden zum Antworten