Objektorientierte Programmierung in der Schule



  • Ein Objekt kapselt seine Daten und seine Methoden.

    d.h. das Objekt selbst muss sich selbst berechnen.

    gibst ne Methode Fläche in Quadrat.

    kann man sie Überlagern in Rechteck, Quader, Würfel (bzw sollte man auch).



  • Vererbung ist nicht dazu da um Coderedudanzen zu vermeiden.



  • Wenn du B von A erben läßt, dann ist B ein A. Ein Quader ist kein Quadrat



  • Vererbung ist nicht dazu da um Coderedudanzen zu vermeiden.

    Hab ich das gesagt?



  • Ja hast du, du hast gesagt die Art der Vererbung wäre ok, weil sie ja alle die Flächenberechnung gemein haben.



  • Grad auch dadurch das erste Problem aufgetreten.
    Das Quadrat hatte noch eine Prozedur setArea, man konnt ja von der Fläche auf die Seite zurückschließen. Beim Rechteck gehts nun nicht mehr. Aber was soll man nun mit der virtuellen Prozedur anfangen? Da sieht man schon, dass das absolut nciht sinnvoll ist.



  • Leider kann ich fast kein Stück Delphi!

    class Quadrat{
    	int a;
    
    	Quadrat(int a){
    		this.a = a;
    	}
    
    	int flache(){
    		return a*a;
    	}
    }
    
    class Wuerfel extends Quadrat{
    	Wuerfel(int a){
    		super(a);
    	}
    
    	int flache(){
    		return 6*a*a;
    	}
    }
    
    class Rechteck extends Quadrat{
    	int b;
    
    	Rechteck(int a, int b){
    		super(a);
    		this.b = b;
    	}
    
    	int flache(){
    		return a*b;
    	}
    }
    
    class Quader extends Rechteck{
    	int c;
    
    	Quader(int a, int b, int c){
    		super(a, b);
    		this.c = c;
    	}
    
    	int flache(){
    		return 2*a*b+2*a*c+2*b*c;
    	}
    
    }
    
    public class vererbung {
    	public static void main(String[] args) {
    		System.out.println(new Quadrat(2).flache());
    		System.out.println(new Wuerfel(2).flache());
    		System.out.println(new Rechteck(2,3).flache());
    		System.out.println(new Quader(2,3,4).flache());
    	}
    }
    


  • @Zeus: *LOL* berechne mal die Fläche von 'nem Würfel. Erst denken, dann schreiben!



  • Warum soll man nicht die (Ober-)Fläche von nem Würfel berechnen können, du Held? 😕



  • ich hab den fehler schon berichtigt das stand a*a*a anstelle von 6*a*a
    und da Volumen != Fläche ist - naja ich darf wohl auch paar Bugs Programmieren.



  • Wenn jemand mal einen Link zum Thema Vererbung hat der ihm nahe bringt, das Vererbung eine ist ein Beziehung ist, dann her damit...

    Also das sollte in *jedem* Buch über OOD/OOP drinstehen.

    Vielleicht hilft dir Barbara Liskovs "Substitution Principle". Schön erklärt von Uncle Bob: http://www.objectmentor.com/resources/articles/lsp.pdf





  • Vielleicht sollte ich schreiben, dass das Java Code ist !



  • Wozu, das sieht man doch. Auch in Java gelten grundlegende OO-Prinzipien 🙂



  • Erfüllt eine Funktion die einen Pointer oder eine Referenz auf eine Basisklasse erwartet eine bestimmte Aufgabe, so muss diese Funktion die selbe Aufgabe auch mit einem Objekt einer abgeleiteten Klasse erfüllen können.

    Tut mein Code das nicht ? Also ich sehe die Verletzung des Prinzip nicht!



  • Dann schau doch bitte hin.



  • Bei dir gilt schon die IST-EIN-Beziehung nicht. Ein Rechteck ist eben im Allgemeinen kein Quadrat. Wenn du also eine Methode hast, die mit Quadraten arbeitet und von typischen Quadrat-Eigenschaften ausgeht (z.B. dass es 4 Seiten hat, die alle gleich lang sind), wird sie kolossal durcheinanderkommen, wenn du ihr ein Rechteck oder gar einen Quader unterschiebst. Deine Vererbung lässt also keine Polymorphie zu.



  • Dann frage ich mich Warum das hier klappt?

    class Quadrat{
    	int a;
    
    	Quadrat(int a){
    		this.a = a;
    	}
    
    	int flache(){
    		return a*a;
    	}
    }
    
    class Wuerfel extends Quadrat{
    	Wuerfel(int a){
    		super(a);
    	}
    
    	int flache(){
    		return 6*a*a;
    	}
    }
    
    class Rechteck extends Quadrat{
    	int b;
    
    	Rechteck(int a, int b){
    		super(a);
    		this.b = b;
    	}
    
    	int flache(){
    		return a*b;
    	}
    }
    
    class Quader extends Rechteck{
    	int c;
    
    	Quader(int a, int b, int c){
    		super(a, b);
    		this.c = c;
    	}
    
    	int flache(){
    		return 2*a*b+2*a*c+2*b*c;
    	}
    
    }
    
    public class vererbung {
    	public static int summe(Quadrat[] q){
    		int sum = 0;
    		for(int i = 0; i < q.length; ++i)
    		{
    			sum += q[i].flache();
    		}
    
    		return sum; 
    	}
    
    	public static void main(String[] args) {
    		Quadrat[] q = new Quadrat[4];
    
    		q[0] = new Quadrat(2);
    		q[1] = new Wuerfel(2);
    		q[2] = new Rechteck(2,3);
    		q[3] = new Quader(2,3,4);
    
    		System.out.println(q[0].flache());
    		System.out.println(q[1].flache());
    		System.out.println(q[2].flache());
    		System.out.println(q[3].flache());
    		System.out.println(summe(q));
    	}
    }
    


  • Weil deine Funktion nicht davon ausgeht ein Quadrat zu bekommen, sondern lediglich ein Ding, was eine Fläche hat. Eine dem angemessene Vererbungsstruktur dafür wär also, dass Quadrat, Rechteck etc. von der abstrakten Klasse/Interface Flaeche abgeleitet sind oder so.
    Es sagt ja keiner, dass deine Struktur nie funktioniert. Nur dass sie etwas kommuniziert, was sie nicht leisten kann, und daher schlechter OO-Stil ist.



  • Also ich sehe nicht die Verletzung des Prinzip !

    Das kommt auf die Verträge an, die du für deine Methoden festlegst. Wenn du überhaupt nichts garantierst, dann kannst du auch alles von allem ableiten ohne das Prinzip zu verletzen (eine Funktion die eine Basisklassenreferenz erhält bekommt keinerlei Garantien, also kann auch nichts verletzt werden).
    Nur gewinnst du dann nichts:

    class Banana
    {
    public:
        virtual void turn_yellow() {...}
        virtual void chop() {...}
        virtual void peel() {...}
    };
    
    // a monkey is a special case of banana except it doesn't peel, turn_yellow 
    // or chop. It does jump, squeal, swing_from_trees though.
    class Monkey : public Banana
    {
    public:
        // Basisklassenmethoden zu NOPs machen...
        virtual void turn_yellow() {}
        virtual void chop() {}
        virtual void peel() {}
    
       // ...und neue Methoden hinzufügen
        virtual void jump() {...}
        virtual void squeal() {...}
        virtual void swing_from_tree() {...}
    
    };
    

    Wenn du, wie in deinem Fall, nur eine Methode hast und nichts weiter garantierst, als dass diese Methode den Flächeninhalt des Objekts liefert, dann ist das auch ok. Sobald deine Klasse aber wirklich sinnvolles Verhalten hat, bekommst du Probleme.

    Quadrat ist kein Rechteck und Rechteck kein Quadrat. Beides sind Spezialisierung von Shape:

    class Shape 
    {
    public:
        virtual int flaeche() = 0;
    };
    
    class Quadrat : public Shape
    {
    ...
    };
    
    class Rechteck : public Shape
    {
    ...
    };
    

Anmelden zum Antworten