Unterschied zwischen abstrakten Klassen und Interfaces

  • Allgemein

Es gibt 45 Antworten in diesem Thema. Der letzte Beitrag () ist von iCanNonIc.

    Unterschied zwischen abstrakten Klassen und Interfaces

    Da ich nicht so ganz verstehe wieso man Interfaces nutzen sollte wollte ich hier nochmal nachfragen.
    1). Welche Vorteile hat ein Interface gegenüber abstrakten Klassen außer Mehrfachvererbung? Ich sehe eigentlich nur den Nachteil, dass Interfaces noch nichts eigenes implementieren können.
    2). Sind Interfaces also einfach nur ein Bauplan? Bzw. ein Bauplan eines bestimmten Teils einer Klasse?
    @Telcrome: Eine sehr interessante Frage. Wiki redet da um den heißen Brei herum, sieh Dir aber mal an, was die MSDN dazu schreibt.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Okay, wenn ich deinen Link richtig verstanden habe müsste das also so sein:
    1). Vorteile von Interface gegenüber abstrakten Klassen?
    - Mehrfachvererbung
    - Sonst eigentlich keine, Polymorphie ist ja auch bei beidem gegeben...
    Definieren Sie bevorzugt Klassen statt Schnittstellen

    2). Sind Interfaces also nur ein Bauplan
    Ja

    In späteren Versionen einer Bibliothek können Sie Klassen problemlos neue Member hinzufügen. Schnittstellen können Sie keine Member hinzufügen, ohne die Konsistenz des Codes zu zerstören.
    ich fasse Klassen immer als Bauplan auf, und mit dem Schlüsselwort New wird eine Instanz davon "gebaut". gugge VeryBasics

    Interfaces sind Verträge, die erzwingen, dass die im Interface spezifizierten Methoden, Properties, Events auch tatsächlich vorhanden sind.

    zB eine Klasse, die IDisposable implementiert, garantiert, dass sie eine Sub Dispose() verfügbar macht.

    Ich weiß auch nicht, was das Gerede von Vererbung bei Interfaces für einen Sinn haben soll. Es ist etwas total anneres.
    Gut, Polymorphie kommt bei beiden raus:
    • Bei Vererbung erbt die Kindklasse die Property vonne Basisklasse
    • Bei Interface besteht ein Vertrag, dass die Property existiert.

    Aber das Implementieren von Interfaces ist keine Vererbung, schon garkeine Mehrfachvererbung!

    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „ErfinderDesRades“ ()

    naja, ich hänge an meiner Definition von Klasse als Bauplan für Objekte, und mit Sub New() wird eins gebaut - gugge VeryBasics
    Auch binnich fast froh, dass vb.net und c# keine Mehrfachvererbung kennen, weil Einfach-Vererbung kann man viel besser an Real-World-Beispielen plausibel machen:
    Nämlich was inne Informatik als Vererbung von Klassen bezeichnet wird, ist der realen Welt als "Abstammung" geläufig.

    Beispielsweise die Klasse Mensch stammt ab von irgendeinem Ur-Säugetier, deswegen das mit den 4 Gliedmaßen, was ja nicht unpraktisch ist.
    Hunde haben auch Gliedmaßen, vom selben Ur-Säugetier geerbt.

    Kreuzspinnen haben auch Gliedmaßen, aber die sind absolut nicht vonnem Säugetier geerbt, und es gibt glaub auch keine gemeinsame Vorform menschlicher und Spinnlicher Gliedmaßen.
    Aber zB. die Milben haben gemeinsame Vorfahren mit der Kreuzspinne, und da auch ihre Gliedmaßen her.

    Also Menschen und Hunde haben Säugetierbeine geerbt, und Kreuzspinne und Milbe haben Spinnenbeine geerbt.
    Dassis Vererbung: Übernahme und Erweiterung der Basisklasse (des Vorfahren).

    Mehrfachvererbung hätte iwie was perverses, monströses: Für ein SpinnenSäugetier müsste man iwie 2 grundverschiedene Ur-Arten zu einer einzigen zusammenschmelzen, und heraus käme ein Wesen mit einem Chitinpanzer und gleichzeitig einem Knochenskelett.
    So Verschiedenheiten zusammenzumergen hätte der Computer übrigens das geringste Problem - inne Informatik problematisch sind mehrfachvererbte Gemeinsamkeiten: Beispiel HundeMensch: Kriegt der Hände oder VorderPfoten?

    So, jetzt das mit den Verträgen:
    Alle diese Viecher haben Gliedmaßen, unds ist egal, ob und wo sie die geerbt haben, oder ob sie sie selbst erfunden haben, jedenfalls haben sie Gliedmaßen und bewegen sich damit fort. "Gliedmaßen-Wesen" könnte also ein Interface sein, und man könnte auch einen Roboter bauen, der dieses implementiert.
    Unds gibt noch weitere Verträge: die Viecher haben alle Augen, und ein Atmungssystem. (Das mit den Augen kriegen die Roboter vlt. noch hin - Atmung wird schwierig) (Ups! Milben haben keine Augen)

    Also es sollte direkt plausibel sein, dasses kein Problem ist, mehrere Verträge zu erfüllen, grad weil Vertrag nix mit Abstammung (Vererbung) zu tun hat.

    Und ich sehe absolut keinen Grund, mir jetzt mit Gewalt ein Interface als Klasse vorzustellen, in die ich keinen Code schreiben kann.
    In ein Interface kann ich einfach deswegen keinen Code schreiben, weils keine Klasse ist.

    Ebenso, wie ein Vertrag kein Vorfahre ist (Vertrag: erfüllen - auch mehrere, Vorfahre: abstammen - nur einer).

    Dieser Beitrag wurde bereits 9 mal editiert, zuletzt von „ErfinderDesRades“ ()

    ErfinderDesRades schrieb:

    naja, ich hänge an meiner Definition von Klasse als Bauplan für Objekte, und mit New wird eins gebaut.
    Und wie willst du eine abstrakte oder statische Klasse instanzieren?
    Ich finde da die Definition von Artentus wesentlich einfacher, kürzer und treffender.


    Opensource Audio-Bibliothek auf github: KLICK, im Showroom oder auf NuGet.
    eine abstrakte Klasse ist ein unvollständiger Bauplan: die Erben müssen ihn vervollständigen.
    An dieser Stelle hinkt der Vergleich mitte Evolution, denn die Evolution hat natürlich nur vollständige Baupläne hervorgebracht.
    Aber ein unvollständiger Bauplan sich vorzustellen scheint mir durchaus einfach: Denke dir eine Klasse MustInherit HausBase, wo das Dach nicht ausprogrammiert ist. Von dieser Klasse erben könnten sowohl "Kirche" als auch "Schule" als auch "Wohnhaus", und jeweils ein komplett anneres Dach implementieren.

    eine statische Klasse ist eiglich keine Klasse im Sinne objektorientierter Programmierung - hat ja mit Objekten nicht das geringste zu tun.
    Ist einfach ein Sammelsurium statischer Methoden, Properties, Events. In VB gibts übrigens garkeine statischen Klassen, dort bezeichnet man das als Module.

    Artentus' Definition erklärt iwie garnix: Weder was eine Klasse ist, noch was eine abstrakte Klasse, noch was Vererbung, noch was Mehrfachvererbung.

    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „ErfinderDesRades“ ()

    ich hab übrigens ziemlich lange über deine Definition gehirnt.
    Und wenn man von c++ kommt, ist einem die vermutlich total eingängig.
    c++ kennt ja Mehrfachvererbung, und wennich c++ richtig begriffen hab, kennen die gar keine Interfaces, weil das Konzept "Vertrag" lösen die ebenfalls mit ihrem MehrfachVererbungs-Konzept.

    Auch sonst binnich über deinen Post total happy, denn erst in der Auseinandersetzung damit bin ich auf den Begriff "Abstammung" gekommen, sodassich jetzt mit ich finde sehr plausiblen Analogien aufwarten kann, um OOP zu erklären:

    Quellcode

    1. Klasse = Bauplan: definiert, was ein Objekt "kann"
    2. Objekt = das anhand des Bauplans Gebaute - die "Instanz"
    3. Vererbung = Abstammung
    4. Interface = Vertrag

    Übrigens kennt auch vb/c# Mehrfachvererbung, allerdings ausschließlich bei Interfaces - bei Interfaces ist sowas kein Problem:

    VB.NET-Quellcode

    1. Interface bla : Inherits IEnumerable, IList
    2. Property BlaBla As String
    3. End Interface
    bla beerbt sowohl IEnumerable als auch IList
    Und der Irrwitz ist - kannste im ObjectBrowser nachgugge - IList beerbt IEnumerable!
    Also bla beerbt IEnumerable doppelt - und das geht.

    Wieder Analogie zu Verträgen
    Ich habe den Vertrag geschlossen, dassich meine Blumen gieße.
    Nun habich den Job als Hausmeister angetreten, und das beinhaltet, dassich alle Blumen gieße im Haus.
    Jo, bei Verträgen ist das kein Problem - indem ich meinen Hausmeister-Vertrag erfülle, gieße ich logisch auch meine eigenen Blumen mit :D

    ErfinderDesRades schrieb:

    Mehrfachvererbung, allerdings ausschließlich bei Interfaces
    Streng genommen können Interfaces nicht vererbt werden. Nur da wir schon so schön am philosophieren sind.


    Opensource Audio-Bibliothek auf github: KLICK, im Showroom oder auf NuGet.
    hä?
    Wie erklärst du dann og. gültiges Code-Beispiel:

    VB.NET-Quellcode

    1. Interface bla : Inherits IEnumerable, IList
    2. Property BlaBla As String
    3. End Interface
    Inherits ist englisch, und heist auf Deutsch numal: "erbt"

    Also ich stimme dir zu, wenn du meinst, dass Vererbung im Sinne von "Abstammung" bei Interfaces nicht so richtig trifft.
    Bei Inteface, aufgefasst als "Vertrag" würde "erben" eher so was bedeuten wie "beinhalten": also mein Hausmeister-Vertrag beinhaltet natürlich, dassich auch meine eigenen Blumen gieße.

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „ErfinderDesRades“ ()

    Muss nochmal eine Frage dazu stellen.

    ErfinderDesRades schrieb:

    Denke dir eine Klasse MustInherit HausBase, wo das Dach nicht ausprogrammiert ist. Von dieser Klasse erben könnten sowohl "Kirche" als auch "Schule" als auch "Wohnhaus", und jeweils ein komplett anneres Dach implementieren.

    Und was ist an dieser Stelle der Unterschied zu einem Interface? Dass die Wände und Fenster schon inklusive sind, aber das Dach variabel gestaltet werden kann? Und ein Interface sagt nur, dass es Fenster, Wände und Dach geben MUSS?
    HausBase ist ja weitestgehend ausprogrammiert - nur das Dach fehlt.

    Bei einem Interface IHaus ist garnix ausprogrammiert. Das gibt dir einerseits mehr Variationsmöglichkeiten, macht annererseits aber auch mehr Arbeit.

    Ist oft eine wesentliche Design-Entscheidung, wenn man grundsätzlich Ähnliches, aber im Detail unterschiedliches hat: Legt man Ähnlichkeiten per Interface zusammen oder per gemeinsame Basisklasse?
    (abstrakte) Klassen und Vererbung finden in VersuchsChat recht trickreich Verwendung.

    Selbstgebastelte Interfaces brauche ich fast nie.
    Hingegen Framework-Interfaces andauernd, etwa IDisposable, ICloneable, INotifyPropertyChanged, und ganz exzessiv IEnumerable(Of T) - letzteres wird ja in jeder ForEach-Schleife genutzt - egal, was da eiglich durchgenudelt wird.
    Ich habe mal eine Log-Klasse versucht abstrakt zu basteln (ist vielleicht auf ein wenig Oversized aber leicht zu verstehen)
    Das ganze basiert auf dem Observer Pattern.

    Es gibt unterschiedliche Varianten von Log Methoden. Bsp. in ein File, die Eriegnisanzeige, Datenbank oder auch nur ins debug.Print.
    Hierzu hab ich mir einfach ein Interface ILogging erstellt welches eine Methode PerformLog beinhaltet.
    Nun hab ich meine 4 Klassen welche alle dieses Interface implementieren, jeder aber anders loggt (Eventlog, File, ...)

    Zusätzlich hab ich eine Klasse welche den LogManager spielt. Dieser beinhaltet eine List(Of ILogging) wo alle verschiedenen Logger sich "anmelden" müssen.
    Dies geschieht über eine AddLogger(Logger as ILogging) (und RemoveLogger zum entfernen).

    Der Manager hat eine Methode PerformAll() wo alle aus der List(Of ILogging) durchlaufen werden und deren PerformLog Methode ausgeführt wird.
    Der Manager muss nicht wissen was innerhalb der PerformLog() passiert. Dies muss einfach korrekt in den Klassen, welche ILogging implemetieren, ausprogrammiert sein.

    Das gute darin ist, dass wenn eine neue Logging-Art dazukommt, wieder nur ILogging implementiert werden muss um es der Liste hinzufügen zu können.
    Also leicht erweiterbar.

    lg
    ScheduleLib 0.0.1.0
    Kleine Lib zum Anlaufen von Code zu bestimmten Zeiten