Logik Problem Konstrukor Mehrfahrvererbung (CStoll du wirst heute gefordert ;) )



  • @Boris: Auf mich wirkt das auch wie falsch verstandene Mehrfachvererbung. Selbst beim Beispiel mit dem Hybridmotor würde ich das viel eher so lösen:

    class Antrieb{
    
    };
    
    class Verbrennungsmotor : public virtual Antrieb{
    
    };
    
    class Elektromotor : public virtual Antrieb{
    
    };
    
    class HypridAntrieb {
     Verbrennungsmotor vmotor; 
     Elektromotor emotor;
    
    };
    

    der Hybridantrieb _hat_ einen Verbrennungsmotor und einen Elektromotor, aber es _ist_ weder das eine noch das andere.

    Du hast ja auch Arme, Beine und nen Kopf, aber bist Du deswegen ein Arm? Würdest Du einen Menschen vom Arm ableiten? Deine Beispiele wirken bisher auf mich wie falsch verstandene Mehrfachvererbung.



  • @skals: Ohman, du kommst mir gerade zuvor... genau diese löung kamm mit grad auch als Altenative im Sinn.

    ABER: Wobei ein Hybridantrieb ein Antrieb ist, sowie Verbrennungsmotor und Ellektromotor, nur eine Kombination.... Er erbt die eigenschaften beider Antriebe, und benutr die gleiche Antriebswelle an die Hinterachse (Wenn diese als Member der Antriebsklasse wäre). Und dise Antriebswelle würde in deinem Beispiel ja nun jetzt 2 mal vorkommen, obwohl beide antriebe an der gleiceh Antriebswelle zerren.... (Hoffe ihr versteht was ich meine)

    class Antrieb{
    
    };
    
    class Verbrennungsmotor : public virtual Antrieb{
    
    };
    
    class Elektromotor : public virtual Antrieb{
    
    };
    
    class HypridAntrieb {
    
     Antrieb **pAntrieb = new *Antrieb[2];
     p[0]= new Verbrennungsmotor(); 
     p[1]= new Elektromotor();
    
    };
    


  • Wenn es schon ein Antrieb ist, dann richtig 🙂

    class Antrieb
    {
        virtual void starten() = 0;
        virtual void vErhoehen() = 0;
    };
    
    class Elektromotor : public Antrieb
    {
        void starten()
        {
            //Strom an!
        }
    
        void vErhoehen()
        {
            //mehr Saft
        }
    };
    
    class Verbrennungsmotor : public Antrieb
    {
        void starten()
        {
            //"etwas" komplizierter
        }
    
        void vErhoehen()
        {
            //mehr Sprit
        }
    };
    
    class Hybridantrieb : public Antrieb
    {
        Verbrennungsmotor vmotor;
        Elektromotor emotor;
    
        void starten()
        {
            emotor.starten();
        }
    
        void vErhoehen()
        {
            if(geschwindigkeit < x)
                emotor.vErhoehen();
            else
            {
                vmotor.starten();
                vmotor.vErhoehen();
            }
        }
    };
    

    PS: Virtuelle Vererbung brauchst du bei deinem Beispiel nicht, da du beim Ableiten jede Basis nur genau einmal hast.



  • BorisDieKlinge schrieb:

    @otze: Rein technisch gesehen schon, aber der eltrokmotor ist ja im prinziop ein hilfsmotor für beschleunigungen, und ein zusätzliche bremswirkung (baterieladen). Wenn der Tank leer ist, wird sich das auot nich mehr zu näcsht teankstelle schleppen können (auser sie ist nur 2 km entfernt). Vergleichbar mit einem Kondensator welche kurzfristige benötigete energiespitzen ausgleicht;)

    Wenn du das so siehst, kann er womöglich als Verbrennungsmotor durchgehen, aber nach der Beschreibung ist er definitiv kein (reiner) Elektromotor. Aber viande's Ansatz dürfte die Abhängigkeiten wohl besser beschreiben.

    (und wenn du schon so fein unterscheiden willst, daß du das Auto bis auf die Antriebswelle zerlegen willst - dann wird die ein eigenständiger Bestandteil des Autos und kein Teil des Motors)



  • Würde ich im der Klasse Antrieb eine Variable X hinzufügen, dann hätte ich ja in deR klasse Hybridmotor ein vererbtes X Elemtne, und jeweils aus dem VErbrenungsmotor und Eltrkotrmotor ein vererbtes X... (seh ich das richtig?)

    Aber die klasse Hybridmotor soll ja nur ein X für alle Abgeleiten klassen haben.. (Gemeinsames Nuten des X's)



  • BorisDieKlinge schrieb:

    ABER: Wobei ein Hybridantrieb ein Antrieb ist, sowie Verbrennungsmotor und Ellektromotor, nur eine Kombination.... Er erbt die eigenschaften beider Antriebe, und benutr die gleiche Antriebswelle an die Hinterachse (Wenn diese als Member der Antriebsklasse wäre). Und dise Antriebswelle würde in deinem Beispiel ja nun jetzt 2 mal vorkommen, obwohl beide antriebe an der gleiceh Antriebswelle zerren.... (Hoffe ihr versteht was ich meine)

    Sorry, das stimmt einfach so nciht. So wie Du den Hybridantrieb beschreibst müßte das _ein_ Motor sein der sowohl Verbrennungsmotor als auch Elektromotor in einem ist. wenn Du aber mal in so ein Hybridauto reinschaust, dann sind da zwei getrennte Motoren drin, einer der auf Brennstoff läuft und energie erzeugt, ein zweiter der eben auf jeder energie läuft.



  • BorisDieKlinge schrieb:

    Aber die klasse Hybridmotor soll ja nur ein X für alle Abgeleiten klassen haben.. (Gemeinsames Nuten des X's)

    Und was soll dieses X überhaupt darstellen? Normalerweise braucht die (nebenbei abstrakte) Basisklasse 'Antrieb' überhaupt keine eigenen Attribute - die hat nur pur virtuelle Methoden wie starten(), beschleunigen(), etc.



  • BorisDieKlinge schrieb:

    ABER: Wobei ein Hybridantrieb ein Antrieb ist, sowie Verbrennungsmotor und Ellektromotor, nur eine Kombination.... Er erbt die eigenschaften beider Antriebe, und benutr die gleiche Antriebswelle an die Hinterachse (Wenn diese als Member der Antriebsklasse wäre). Und dise Antriebswelle würde in deinem Beispiel ja nun jetzt 2 mal vorkommen, obwohl beide antriebe an der gleiceh Antriebswelle zerren.... (Hoffe ihr versteht was ich meine)

    Du musst dir aber schon im Klaren sein, dass es nicht immer Sinn macht etwas aus der realen Welt beim Modellieren 1:1 abzubilden. Oft kann man vereinfachen, weil man viele Details gar nicht braucht und oft ist das Abbilden auf eine Klassenhierarchy gar nicht möglich.

    Ein gutes Beispiel ist ein Rechteck und ein Quadrat. Letzteres ist ein Spezialfall des ersteren trotzdem könntest du Quadrat nicht von Rechteck ableiten, da das Rechteck zwei variable Seiten hat und das Quadrat nur eine.



  • aber man könnte das rechteck vom quatrat ableiten....oder nich



  • BorisDieKlinge schrieb:

    aber man könnte das rechteck vom quatrat ableiten....oder nich

    Nein, umgekehrt. Ein Quadrat ist-ein Rechteck, aber ein Rechteck ist eben nicht unbedingt ein Quadrat.



  • lolz schrieb:

    Ein gutes Beispiel ist ein Rechteck und ein Quadrat. Letzteres ist ein Spezialfall des ersteren trotzdem könntest du Quadrat nicht von Rechteck ableiten, da das Rechteck zwei variable Seiten hat und das Quadrat nur eine.

    Also, meinem Verständnis der OOP zufolge könnte (und würde) man das sehr wohl so machen. Dann werden die Setter-Methoden für Länge und Breite eben virtuell und 'Quadrat' überschreibt sie entsprechend, um sicherzustellen, dass stets gilt Länge = Breite.



  • Ja, aber damit zerstörst du die Invarianten des Rechtecks - und wenn 'quadrat' ein 'rechteck' sein soll, muß es sich auch wie eins verhalten:

    void modify(rechteck& r)
    {
      r.setHeight(10);
      r.setWidth(15);
      //für ein normales Rechteck ist diese Anforderung erfüllt, also sollte die Assertion funktionieren
      assert(r.getHeight()==10 && r.getWidth()==15);
    }
    
    ...
    quadrat q;
    modify(q);
    //Das Quadrat sichert zu, daß stets Höhe=Breite gilt, also wird der assert() in modify() zuschlagen
    
    //und wenn die Klasse Quadrat so gebaut ist, daß modify() durchläuft, ist sie
    //unbrauchbar, weil sie ihre eigenen Invarianten nicht erfüllt:
    assert(q.getHeight()==q.getWidth());
    


  • Hi,

    auch wenn's leicht OT ist: Ich habe eigentlich immer dasselbe Problem "Spezialisierung durch Vererbung".
    Nicht, dass ich nicht verstehe, wie man es "machen kann", sondern eher ein konzeptionelles:

    • die Anzahl der Attribute legt die "Freiheitsgrade einer Klasse fest
    • Bei Vererbung kann man lediglich Attribute hinzufügen
    • unter "Spezialisierung" verstehe ich im Alltagsleben (auf das sich all diese Beispiele immer beziehen) die Reduzierung von Freiheitsgraden (Ein Quadrat hat unabhängige Größe weniger als ein Rechteck (Attribut) (*), bei einem Kreis ist eine Rotation um den Schwerpunkt sinnlos, bei einer Ellipse sinnvoll (Funktion), ...)

    (*) Die übliche Erklärung: "Ja, die sind dann eben gleich - muisst Du eben in Funktionen für sorgen!" überzeugt mich nicht. Ebenso könnte ich einem Quadrat auch weitere künstliche Eigenschaften anderer Figuren verpassen (Radius, Höhe, Brennpunkt, ...) und die mittels Sonderbehandlung irgendwie hinbiegen....
    EDIT: CSToll hat in der Zwischenzeit ein Beispiel dafür gebracht.

    Vielleicht habe ich auch noch etwas Grundlegendes nicht verstanden, aber ich habe eher den Eindruck, dass man hier eine Technik (Vererbung) erfunden hat, die sich nur teilweise für die Umsetzung einer Logik (Spezialisierung) nutzen lässt, aber eben kein komplettes Äquivalent darstellt.
    Kann mich sonst mal jemand aufklären, wo ich falsch liege ?

    Gruß,

    Simon2.



  • ups ja das meinte ich, das quatrat vom rechteck ableiten....



  • Grr, bei dem Quadrat-Beispiel bin ich natürlich genau in die übliche OOP-Falle getappt. Vererbung funktioniert natürlich genau andersherum. Charles Petzold verwendet als Illustration immer das Beispiel eines 3D-Vektors und eines 2D-Vektors. Mathematisch gilt eindeutig, ein 2D-Vektor ist-ein 3D-Vektor (in dem die z-Koordinate stets null ist). Programmiertechnisch würde man es aber genau andersherum umsetzen, da wird ein 2D-Vektor erweitert.

    Wobei man hier vorsichtig sein muss, weil ich nicht weiß, ob Petzold OOP verstanden hat, schließlich war bis vor kurzem C seine Lieblingssprache. 😉



  • Programmtechnisch würde ich keinerlei Vererbungsbeziehung zwischen 2- und 3-dimensionalen Vektoren anbieten - die Klassen sind im praktischen Einsatz zu unterschiedlich (und z.B. v.getLength()==sqr(v.x*v.x+v.y*v.y) gilt nicht mehr, wenn als 'v' plötzlich ein 3D-Vektor ankommt).

    (und generell solltest du gute Gründe haben, etwas von einer nicht-abstrakten Klasse abzuleiten - das kann schneller schief gehen als dir lieb ist)


Anmelden zum Antworten