OOP ohne Vererbung?



  • naja schrieb:

    Zeus schrieb:

    Für Polymorphie brauch ich keine Interfaces 😃

    Und wie machst du das dann, wenn du keine Vererbung hast? Und statische Polymorphie ist hier nicht gefragt.

    In C und C++ wären zum Beispiel Funktionszeiger (oder eine Abstraktion davon) eine Möglichkeit. Aber auch diese haben ihre Einschränkungen.



  • Nexus schrieb:

    naja schrieb:

    Zeus schrieb:

    Für Polymorphie brauch ich keine Interfaces 😃

    Und wie machst du das dann, wenn du keine Vererbung hast? Und statische Polymorphie ist hier nicht gefragt.

    In C und C++ wären zum Beispiel Funktionszeiger (oder eine Abstraktion davon) eine Möglichkeit. Aber auch diese haben ihre Einschränkungen.

    sag gleich, daß if ausreicht. stattdessen switch oder funktionszeigertabellen zu nehmen ist nur unbedeutende geschwindigkeitssteigerung.



  • Nexus schrieb:

    naja schrieb:

    Für Polymorphie kannst du auch Interfaces nehmen.

    Nur sehr beschränkt. Ohne das Vorhandensein von Daten können viele hierarchische Strukturen nicht abgebildet werden. Ich erachte schon das Fehlen von Mehrfachvererbung in manchen Fällen als Einschränkung, Vererbung komplett wegzulassen scheint mir keine gangbare Alternative zu sein.

    Man kann ja ein Interface implementieren und gleichzeitig eine has-a Beziehung zum Objekt, von dem du Daten brauchst, haben.

    Übrigens habe ich nie gesagt, dass ich Vererbung ganz abschaffen würde, sondern nur die Alternativen aufgezählt. Ob man ganz ohne Vererbung auskommt (irgendwie sicher) und ob das dann besser oder schlechter ist, habe ich mir noch nie überlegt.

    Nexus schrieb:

    naja schrieb:

    Zeus schrieb:

    Für Polymorphie brauch ich keine Interfaces 😃

    Und wie machst du das dann, wenn du keine Vererbung hast? Und statische Polymorphie ist hier nicht gefragt.

    In C und C++ wären zum Beispiel Funktionszeiger (oder eine Abstraktion davon) eine Möglichkeit. Aber auch diese haben ihre Einschränkungen.

    Was von der Idee her auch ein einfaches Interface ist. Nur nicht das was ich dachte was du mit "Objekte als Basisobjekte behandeln" meinst. Ich dachte du beziehst dich da auf Polymorphie.



  • volkard schrieb:

    sag gleich, daß if ausreicht. stattdessen switch oder funktionszeigertabellen zu nehmen ist nur unbedeutende geschwindigkeitssteigerung.

    Kommt drauf an, was man unter Polymorphie versteht. Ich assoziiere damit unter anderem, dass der gleiche Anwendercode je nach Kontext etwas anderes tut, und dass die entsprechende Semantik bei der Verwendung implizit ausgewählt wird. Das ist bei If-Abfragen nicht direkt gegeben, schliesslich schreibt der Programmierer die Fallunterscheidung ausdrücklich hin.



  • Nexus schrieb:

    schliesslich schreibt der Programmierer die Fallunterscheidung ausdrücklich hin.

    Aber er ruft machZeig(ding) auf und das if ist in der Funktion weggekapselt. Er schreibt ja auch die Funktionszeigertabelle explizit hin und (&tab[ding->type])(ding) ist nicht hübsch und man wird es vielleicht wegmakroen.



  • Nexus schrieb:

    Bashar schrieb:

    Das ist keine Eigenschaft der Vererbung.

    Es ist aber eine Beziehung, die durch Vererbung in Sprachen wie Java oder C++ möglich wird. Wollen wir uns über terminologische Feinheiten unterhalten oder sagst du mir gleich, was du an meiner Aussage für falsch hältst?

    Ich hab in meinem ersten Posting hier doch schon gesagt, dass bei Forderungen, Vererbung abzuschaffen, in der Regel mit Vererbung die Implementationsvererbung meint. Das man auch manchmal davon spricht, Interfaces zu vererben, macht die Sache etwas verworren.
    Das Beispiel, was du genannt hattest, also so zu tun, als hätte man ein Objekt eines Typs, das aber in Wirklichkeit ein Objekt eines Subtyps ist, benötigt eben gerade keine Vererbung, sondern lediglich Subtyping. Das ist sogar die Definition des Subtypings nach Liskov.
    Das ist alles keine terminologische Feinheit, sondern entscheidend, um die Forderung der von Artchi zitierten Autoren, Vererbung abzuschaffen, überhaupt zu verstehen.



  • naja schrieb:

    Man kann ja ein Interface implementieren und gleichzeitig eine has-a Beziehung zum Objekt, von dem du Daten brauchst, haben.

    Meinst du nicht, das würde die Sache unnötig verkomplizieren? Schliesslich müsste man das Status-Objekt, das man als Aggregat hält, mit dem Interface konsistent halten. Man müsste für Aktionen, die in einer statusbehafteten Basisklasse durchgeführt werden könnten, im Interface abstrakte Methoden anbieten, diese in der eigentlichen Klasse implementieren und an das Aggregat weiterleiten.

    naja schrieb:

    Was von der Idee her auch ein einfaches Interface ist.

    Das wollte ich damit eigentlich zeigen. 😉

    naja schrieb:

    Nur nicht das was ich dachte was du mit "Objekte als Basisobjekte behandeln" meinst. Ich dachte du beziehst dich da auf Polymorphie.

    Polymorphie muss nicht unbedingt einmal im Spiel sein. Ich habe bei mir oft den Fall, wo ich ein Objekt abstrakt betrachte (d.h. ich kenne nicht die eigentliche Klasse, sondern nur eine Basisklasse davon).



  • volkard schrieb:

    Aber er ruft machZeig(ding) auf und das if ist in der Funktion weggekapselt. Er schreibt ja auch die Funktionszeigertabelle explizit hin und (&tab[ding->type])(ding) ist nicht hübsch und man wird es vielleicht wegmakroen.

    Deshalb auch "nicht direkt". Bei hinreichender Abstraktion erhält man zunehmend polymorphes Verhalten, das stimmt. Wobei der Schritt bei Funktionszeigern meiner Meinung nach viel kleiner ist, aber im Grunde läufts aufs Selbe hinaus, da hast du Recht.

    Bashar schrieb:

    Das Beispiel, was du genannt hattest, also so zu tun, als hätte man ein Objekt eines Typs, das aber in Wirklichkeit ein Objekt eines Subtyps ist, benötigt eben gerade keine Vererbung, sondern lediglich Subtyping. Das ist sogar die Definition des Subtypings nach Liskov.

    Ah, danke für die Erklärung. Ich war wohl zu fixiert auf die übliche Verwendung des Begriffs in einigen Programmiersprachen.



  • naja schrieb:

    Zeus schrieb:

    Für Polymorphie brauch ich keine Interfaces 😃

    Und wie machst du das dann, wenn du keine Vererbung hast? Und statische Polymorphie ist hier nicht gefragt.

    So?

    package hello
    
    object Application {
    
    	class SayHello {
    		def message() = "Hello"
    	}
    
    	class SayAh {
    		def message() = "Ahh"
    	}
    
    	def doit(x : { def message() : String } ) {
    		println(x.message())
    	}
    	def main(args: Array[String]): Unit = {
    		var f = new SayHello
    		var g = new SayAh
    
    		doit(f)
    		doit(g)
    	}
    }
    


  • Und was passiert da, wenn SayHello kein "def message" hätte?



  • Auch gut, aber man könnte es als eine Art unbenanntes Interface auffassen, es scheint mir nichts fundamental anderes zu sein, oder?

    naja schrieb:

    Und was passiert da, wenn SayHello kein "def message" hätte?

    Ein Compilefehler natürlich (hoffentlich), da SayHello nicht der geforderten Signatur entspricht.



  • Ja und jetzt sind wir soweit, Funktionen in Klassen zu packen, nur um sie als Objekt an eine Methode zu uebergeben. Lisp hat das mit first-class-functions eleganter geloest, hinzu kommt noch der ganze CLOS-Kram. Aber hey ... wenn man damit anfaengt, kann man auch gleich aufhoeren zu diskutieren.



  • @naja
    Ja ein Kompilerfehler.

    @Bashar
    Wenn ich fundamental anderes zeigen wollte, hätte ich prototype-based programmiersprache gezeigt, da mir persönlich die Syntax von dennen (JavaScript, Self, Io,...) nicht gefällt, hab ich sein gelassen. Cecil gefällt mir, hat aber Vererbung.

    @knivil
    Der Wunsch von dir wird nachgekommen, die funktionale Version:

    package hello
    
    object Application {
    
    	def sayHello() = "Hello"
    	def sayAh() = "Ah"
    
    	def doit(x : ()=>String ) {
    		println(x())
    	}
    	def main(args: Array[String]): Unit = {
    
    		doit(sayHello)
    		doit(sayAh)
    	}
    }
    

    Was beschreibt nochmal first-class-functions?



  • Das meinte ich, es gibt keine Klassen mehr, nur noch Objekte ... koennen wir jetzt aufhoeren?



  • @Zeus! Um welche Sprache handelt es sich da, die du in deinem Beispiel verwendest?



  • Bulli schrieb:

    @Zeus! Um welche Sprache handelt es sich da, die du in deinem Beispiel verwendest?

    Scala


Anmelden zum Antworten