C# Spaßfrage - ist das Mehrfachvererbung ?

Status
Für weitere Antworten geschlossen.

Micke

Lt. Junior Grade
Registriert
Nov. 2020
Beiträge
505
gegeben sind die Fundamente:
Code:
public abstract class Säugetier
{
    public virtual int AnzahlBeine => 4;

    public void Rennen()
    {
        if (AnzahlBeine > 0)
            Console.WriteLine("rennen");
    }
}

public interface IMeinHaustier
{
    bool KannSchwimmen => true;

    void Schwimmen()
    {
        if (KannSchwimmen)
            Console.WriteLine("schwimmen");
    }
}
Diese werden verwendet in:
Code:
public class Pferd : Säugetier, IMeinHaustier
{
}

public class Hamster : Säugetier, IMeinHaustier
{
    public bool KannSchwimmen => false;
}

Pferde und Hamster schwimmen & rennen mittels
Code:
    void Main()
    {
        Pferd p = new Pferd();
        p.Rennen();
        IMeinHaustier h = new Hamster();
        h.Schwimmen();
    }
Und, Meinungen🙂 ?
 
Zuletzt bearbeitet:
  • Gefällt mir
Reaktionen: Mutex
Lösung
Interessant. Ich bin vor allem in Java bzw. seit ein paar Jahren in Kotlin unterwegs, dachte aber, dass C# sich da wie Java verhält. Java liefert einen Compiler-Error, wenn mehrere Interface Default Methods miteinander im Konflikt stehen. Man muss die Methode dann in der Klasse implementieren und die gewünschte(n) explizit aufrufen. Wenn die Default Methods eindeutig sind, hat die Klasse sie, d.h. man kann sie über eine Variable mit dem Typ der Klasse aufrufen. Antwort #2 überrascht mich.
Ergänzung ()

Der Einwand von tollertyp bezüglich des Abdriftens in Compiler-Details ist nicht ganz unberechtigt. Ich wollte eigentlich noch auf die ursprüngliche Frage zurückkommen, habe aber aufgehört. 🙃

Die Definition von Mehrfachvererbung...
Warum soll das Mehrfachvererbung sein?

Interfaces mit Implementierungen verhalten sich zwar ähnlich wie Mehrfachvererbung, sind aber keine.

Definition von Mehrfachvererbung: Mehrere Basisklassen.
Hier ist es eine Basisklasse und ein Interface. Selbst wenn es 20 Interfaces mit konkurrierenden Implementierungen für Schwimmen wäre, wäre es keine Mehrfachvererbung.
 
  • Gefällt mir
Reaktionen: f00bar
Das Interface IMeinHaustier ist falsch benannt. Das ist ein ISchwimmTier Interface. Die Verwendung eines Interfaces ist hier an sich schon überflüssig. Säugetier klingt nicht nach einer sinnvollen Oberklasse.

Was genau ist deine Frage? tollertyp hat die Frage an sich schon beantwortet. Du willst aber offenbar auf irgendwas hinaus.
 
  • Gefällt mir
Reaktionen: f00bar
C# unterstützt keine Mehrfachvererbung. Punkt. Du wirst sie also nicht gefunden haben.
Weitere Infos dazu beim Hersteller.
 
  • Gefällt mir
Reaktionen: tollertyp, Nero1 und f00bar
Ein Interface ist ein Interface und eine Klasse ist eine Klasse; ein Interface „vererbt“ nichts. Es ist demnach auch keine „Basis“ für eine Vererbung.

Das Interface aus deinem Beispiel enthält ausschließlich Default-Implementierungen und ist damit streng genommen überflüssig.

Möglicherweise willst du darauf hinaus dass sich durch dein Beispiel ein (in mancher Hinsicht) ähnliches Verhalten wie durch Mehrfachvererbung erreichen lässt, allerdings bleibt es dann immer noch ein fragwürdiges Design, wie weiter oben auch schon angemerkt worden ist.
 
  • Gefällt mir
Reaktionen: BeBur und f00bar
Geht mir ähnlich, ich weiß auch nicht, was hier die Spaßfrage sein soll.

@BeBur: Wenn es ISchwimmTier ist, dann frage ich mich aber, wozu es dann noch die Property KannSchwimmen braucht. Bin aber bei dir, dass so ein Interface in dieser Konstellation mehr Sinn ergeben würde.
 
  • Gefällt mir
Reaktionen: f00bar und BeBur
Stelle mir gerade die Frage, ist das vielleicht eine Hausaufgabe, die als Spassfrage benannt wurde?
Wobei unter Spassfrage verstehe ich womöglich etwas anderes.

Die andere Sache mal rein fachlich betrachtet, könnte vielleicht hier die Motivation sein, darauf hinzuweisen, dass mit neuen möglichen Sprach-Features vom C# Compiler evtl. das Diamond-Problem Einzug erhielt?

------------------------------------------------------------------------------------------------------------------------------------
Edit: Nach dem ich mir mal die Antworten hier im Thread nochmal durchgelesen habe, muss ich zugeben, die Frage vom TE scheint doch recht spaßig zu sein...

Genauso, wie eine abstrakte Klasse, ist ein Interface nichts weiter, als eine Abstraktion und tatsächlich verschwimmen bei den neueren C# Compilern die Unterschiede zwischen abstrakten Klassen und Interfaces immer mehr, seit auch Interfaces bereits eine Implementierung mitliefern können.

Und wenn ich es mir recht überlege, bleibt der Unterschied mittlerweile fast nur noch im Schlüsselwort "class" und "interface", 2 Wörter die vom Entwickler an passender Stelle im Quellcode eingetragen werden und dann durch das Kompilieren eh zu einem binären Blob verwurstelt werden, der noch nicht einmal direkt ausgeführt werden kann, sondern dann über den JITER beim Start in ausführbaren Binärcode übersetzt wird, wo es dann nur noch auf Bitschubserei und Registerverbiegen und paar Sprünge rausläuft. Zugegeben mehrere unterschiedliche Interfaces können an einer Klasse spezifiziert werden, auch das ein Unterschied von Interfaces und Klassen in C#.

Das ganze Konstrukt namens OOP ist doch nix weiter als ein abstrakter Versuch, die schwerverständlichen CPU Operationen, die am Ende da rauspurzeln, in eine vom Menschen eher vertraute Denkweise zu pressen! Defakto, wo ist der Unterschied zwischen interface und abstract class? und bitte stützt eure Argumentation nicht rein auf die unterschiedlichen 2 Schlüsselwörter und das was der Prof oder Berufsschullehrer versuchte, euch irgendwann einmal einzutrichtern!

Übrigens ein Freund der Schwester einer Tante erzählte mir, dass es auch Programmiersprachen geben soll, die keine Interfaces kennen, trotzdem OOP machen und alles über abstrakte Klassen abläuft. Ich halte das für ein Einhorn, aber naja, ich habe davon auch keine Ahnung und frage für einen Freund.

Hat jemand Ahnung von Eiffel und wenn ja, gibt es da so Interfaces? (Vorsicht: gefährliches Halbwissen meinerseits! Ich bewege mich auf dünnem Eis, kann aber ehrlich nichts dazu in der Datenschleuder finden.)

Und um da auch mal auf eine ähnliche gelagerte Fragestellung hinzuweisen, was ist bei C++ der Unterschied zwischen "struct" und "class"?
 
Zuletzt bearbeitet:
Kennst du Konstruktoren für Interfaces? Ich ehrlich gesagt nicht. Um nur einen Unterschied zu nennen.
Kann ein Interface von anderen Klassen ableiten? Wäre mir neu.
Aber ja, sind total die selben Dinge und quasi nur ein anderes Schlüsselwort...

Ach ja: Bin mir nicht sicher, ob Object Pascal (z.B. aus Turbo Pascal 5.5), bei dem Klassen mit dem Schlüsselwort "object" definiert wurden, Interfaces kannte.

Wenn wir schon so viel Spaß haben: OOP ist kein abstrakter Versuch, sondern ein Versuch der Abstraktion.
 
  • Gefällt mir
Reaktionen: Raijin
OOP ist kein abstrakter Versuch, sondern ein Versuch der Abstraktion.

Alles eine Frage der Sichtweise :-D Interessant ist unsere gemeinsame Schnittmenge, dass OOP ein Versuch ist, ok gebe mich geschlagen und entferne in meinen Gedanken das Wort "abstrakt" vor dem Wort "Versuch" und frage dich, ist OOP "abstrakt"?

Mal ein anderer Aspekt in der Softwareentwicklung, ich habe es in meinem Umfeld mit vielen Entwicklern zu tun, teils berufsgebildet, teils akademischen Ursprungs, die tatsächlich in jedem Furz einen Unterschied sehen, statt sich wirklich mal der Herausforderung zu stellen in einem Chaos von Begrifflichkeiten und Abstraktionen, dann Gemeinsamkeiten zu entdecken, wenn nicht sogar Muster zu erkennen und diese geschickt miteinander zu kombinieren und Schlüsse daraus zu ziehen. Sie beten stoisch die gelernten Sätze herunter, wie ein "OOP ist kein abstrakter Versuch, sondern ein Versuch der Abstraktion". Können aber nicht den Widerspruch an sich dabei entdecken. Das Ergebnis ist dann massiv viel Code mit richtig vielen "if" und "switches" so brutal zu durchsetzen, dass am Ende sie selbst nach einer Pause von vielleicht mehreren Wochen nicht mehr blicken, was ihr eigener Code bedeutet... Das gibt mir leider sehr zu denken.

Offenheit für andere Sichtweisen fördert Inklusion und vielleicht sogar neue Erkenntnisse die gern auch geprüft und ggf. falsifiziert werden können. ;-) und ich vermute schlicht, dass dies auch der Anstoss dieses Threads bei der provokanten Ansage "Spassfrage" war... Im Grunde läuft bei mir gerade ein Lernprozess an.

Es ist halt so, in C# gibt es Interfaces, in anderen Sprachen nicht, trotzdem schreiben sie sich auch OOP auf die Fahne und was ich eigentlich mit meiner auch recht provokanten Formulierung mal erreichen wollte, war, dass mal ernsthaft darüber nachgedacht wird, dass ein syntaktisches Element, was in C# zu finden ist, vielleicht auch nur Zucker sein kann um den Entwickler was leichter ins Hirn zu pflügen, aber genauso gut alternative Wege eingeschlagen werden können, die zu einem ähnlichen, wenn nicht sogar zum gleichen Ergebnis führen, denn mehrere Alternativen bedeuten mehr Spielraum, haben jeweils ihre eigenen Vor- und Nachteile. Also ja, ich finde mittlerweile, dass es echt eine spassige Frage ist, wenn ich betrachte, wie hier reflexartig Zeug rausgefeuert wird, was in einigen Fachbüchern zu finden ist und nicht der Versuch unternommen wurde, sich dem Thema mal auch nur ansatzweise von einer anderen Sichtweise zu nähern.

Aber hey, gerne lass ich dir den Spass mit "Interface" und denke im Innersten "nö". Zudem ist es schon interessant, dass eine Mehrfachvererbung mit Klassen in C# seit Version 1.0 nicht möglich ist, doch tatsächlich seit der Möglichkeit über Interfaces und implementierten Membern sich genau diese Limitation auch recht nett umschiffen lässt. Noch cooler finde ich die Tatsache, dass der Einsatz von Interfaces nicht rein auf Klassen beschränkt ist, sondern genauso gut einem "struct" aufgepflanzt werden kann, weil damit auch schon wieder eine Limitation fällt, die es seit an Beginn von C# gibt. Structs können nicht erben, aber bei Interfaces, die eine Implementierung mit sich bringen, ist dieses Limit in der Tat dann auch obsolete. Und die richtig geile Wucht entwickelt sich dann, wenn du das selbe Interface auf Klassen und Strukturen gleichermaßen ansetzen kannst und dein Code nicht mehr gezwungen ist, immer nur Klasse oder nur Struktur in einer Art Vererbungslinie zu verwenden.

Keine Ahnung, wie du das siehst, doch irgendwo finde ich diese Spassfrage richtig lustig und nen netten Plottwist in der Geschichte von C#! Und diese Diskussion gerade find ich toll, weil, wie gesagt, bei mir ein Lernprozess entsteht.

Naja, ist schon spät, bis morgen dann

Edit:
@Micke: Bist du ein Softwareentwickler mit Berufspraxis oder machst du es als Hobby? Schreibe mich bitte mal per PM an, denn ich glaube, da tut sich gerade eine interessante Option auf!
 
Zuletzt bearbeitet:
Jedenfalls, wie solcher Code oder lange Vererbungslisten im Einklang mit Microsofts Aussage stehen, daß C# nur EinzelVererbung unterstützt, war ein Vorschlag. Da es eine abwegige Frage ist , ob ich etwas code was offiziell nicht möglich ist, hab ich es Spassfrage genannt.
ReignInBlo0d schrieb:
ein Interface „vererbt“ nichts. Es ist demnach auch keine „Basis“ für eine Vererbung.
Mit der Sicht bist du ja nicht allein. Tatsächlich vererbt aber jedes Interface mindestens Deklarationen.
Und für diese wird MehrfachVererbung unterstützt.

BeBur schrieb:
Du willst aber offenbar auf irgendwas hinaus.
Wohl auch etwas Begeisterung teilen, was mittlerweile geht
 
Zuletzt bearbeitet:
Hey Micke,
cool dass du geantwortet hast! Leider kam ich bei mehrfachen Lesen meines eigenen längeren Pampflets zum Schluß, dass ich wohl lieber doch nicht nach deinem Werdegang frage und das noch mit einer Chance auf eine Option verbinde… Just in dem Moment wo ich meine Frage löschte, hattest du schon geantwortet. Yeah, Shit happens...

Aber insgesamt hätte ich schon Lust drauf mich mit dir zu vernetzen, gerne hier vielleicht später bei den üblichen Verdächtigen.

Zurück zum Thema: Ich dachte bei einer Klasse folgt nach dem Doppelpunkt zuerst die Basisklasse und danach die implementierten Interfaces. Sollte keine Basisklasse angegeben sein, dann wird Object genommen. Spricht man hier tatsächlich von einer Vererbungsliste? Streng genommen ist es tatsächlich eine Auflistung, doch das exakt erste Element in dieser Liste hat in C# eine besondere doppelte Bedeutung. Es kann eine Basisklasse sein oder ein Interface. Genauso ist es möglich keine Auflistung anzugeben, dann schlägt halt der Drache namens Compiler zu und knallt da einfach ein "Object" dahin.

@tollertyp: Interessante Sache, dass ich in meinen vorherigen Post explizit nach dem Unterschied von "interface" und "abstract class" fragte, du dann einfach das Wort "abstract" entferntest, was wiederum insgesamt ne Veränderung der Parameter bedeutet, dementsprechend auch besser zu deiner Antwort passte, aber im Kern nichts mehr mit dem zu tun hatte, worauf ich hinaus wollte!

Was insgesamt vielleicht eine verbesserte Version des Ausgangsposts gewesen wäre, hier nicht nur kurz und knapp eine Frage "Ist das Mehrfachvererbung?" und dann "Meinungen?" zu fragen, sondern schlicht es anders zu formulieren: "Ist es eine Mehrfachvererbung? Und wenn ja, warum?" Ich glaube damit wäre vielleicht etwas schneller der Groschen gefallen, worauf es abzielte... Zumindest wären dann die Propheten keine Propheten mehr, weil sie eben nicht nur eine Weissagung in den Thread pusten, ihre Jünger in Scharen hinterher rennen und die Ungläubigen eher verdutzt aus der Wäsche schauen, weil sie nicht begreifen, worauf Aussagen, wie z.B.

"Definition von Mehrfachvererbung: Mehrere Basisklassen.
Hier ist es eine Basisklasse und ein Interface. Selbst wenn es 20 Interfaces mit konkurrierenden Implementierungen für Schwimmen wäre, wäre es keine Mehrfachvererbung."

tatsächlich basieren.

Im Grunde sind die Interfaces von C# nichts weiter als eine Form von Vertrag, zwischen der Klasse und dem Konsumenten, der aus der Klasse eine Instanz des Objektes erstellt und nutzt. Dieser Vertrag sagt nix weiter, als dass es scheißegal ist, welcher Bauplan (sprich Klasse) da herangezogen wurde, sondern dass eine Instanz des Objektes dir genau die Funktionalitäten liefert, wie es im Vertrag (das Interface) vereinbart ist. Du kannst den gleichen Effekt erzeugen, wenn du eine "abstract class" definierst, haust genauso die Methods, Properties und Events mit dem Schlüsselwort "abstract" in den Body der "abstract class" OHNE eine konkrete Implementierung zu liefern und hast im Kern das Gleiche, wie es ursprünglich seit Beginn der Zeitrechnung in C# als Interface möglich ist. Das Ganze hat auch Unterschiede, z.B. per se gibt es erstmal in C# keine Mehrfachvererbung, zumindest wollten dies die Designer von C# erreichen, wegen Problemen, die man u.a. in C++ hat und bauten eine Limitation von Anfang an ein, die vom C# Compiler dann konkret angemäkelt wird, wenn ein Anfänger 2 Basisklassen in der Auflistung nach dem Doppelpunkt des Klassennamens hinschrieb. Da es aber u.U. sehr sinnvoll sein kann, mehrere Sachen nach dem Doppelpunkt aufzulisten, bietet sich halt eine Liste statt einem einzelnen Namen an dieser Stelle des Quellcodes an. Doch das erste Element hat halt, wie gesagt, diese besondere Doppelrolle und damit kann es leicht fehlinterpretiert werden, dass es eine Vererbungsliste wäre. Aus meiner Sicht ist es nichts weiter als eine Liste, die den Hinweis liefert, was als Grundfunktionalität in deiner Klasse verfügbar ist, nicht mehr nicht weniger. Du kannst jederzeit deine Klasse um zusätzliche Member erweitern, diese sind jedoch dann nicht Bestandteil von Verträgen. OOP braucht nicht zwingend Interface um sich als OOP zu bezeichnen, da auch "abstract class" das Gleiche bewirken können, daher meine Hinweise auf andere Programmiersprachen...

@tollertyp: Ich stelle nicht dein Wissen und deine Erfahrungen in Frage, genauso ist es nicht mein Anliegen dich in irgendeiner Weise anzugreifen. Was mich jedoch an Diskussionen oft stört, wenn Aussagen getroffen werden, ohne das sie begründet werden. Denn es nimmt mir, als Teilnehmer, die Chance hier etwas zu verstehen und somit zu lernen, was eventuell nicht ganz so offensichtlich zu sein scheint. Da aber im Startpost einfach nur nach Meinungen gefragt wurde, ist eigentlich jeder in dieser Runde fein aus dem Schneider. :-D Also von daher alles Tutti-Frutti...

und ich wünsche allen einen schönen Arbeitstag.
 
Zuletzt bearbeitet:
Micke schrieb:
autsch. Ich würde mich aber an deiner Stelle nicht so sehr an einzelne Punkte klammern. Dann fällt evtl. auf, daß sich hinter Doppelpunkten erstaunlich lange Vererbungslisten befinden können. Vielleicht was mit 2 Punkten für's neue Jahr ?
Ich habe nicht die leiseste Ahnung, was du mir mit diesem Geschwurbel zu vermitteln versuchst, aber ich denke ich lege meinen Standpunkt noch mal etwas ausführlicher dar.

Die Frage des Themas lautet: [C#] Spaßfrage - ist das Mehrfachvererbung ?
Dazu stellt sich natürlich zu allererst, ohne eine Zeile Code zu lesen, die Anschlussfrage: Was ist Mehrfachvererbung (multiple inheritance) und wie ist es definiert? Ein kurzer Blick in die deutsche Wikipedia liefert eine erste Anwort:

Bei der Objektorientierten Programmierung handelt es sich um Mehrfachvererbung, wenn eine abgeleitete Klasse direkt von mehr als einer Basisklasse erbt. Ein sequentielles, mehrstufiges Erben wird dagegen nicht als Mehrfachvererbung bezeichnet.

Damit ließe sich die Frage etwas frei auch formulieren: Ist das folgende in C# möglich.

C#:
public class Foo {}

public class Bar {}

public class Foobar : Foo, Bar {}

Die Antwort darauf lautet nein.

Jetzt kann man natürlich den eigentlich genau defnierten Begriff der Mehrfachvererbung "aufweichen" und mit Mehrstufiger-Vererbung (multi-level inheritance) gleichsetzen. Dann ließe sich die Frage formulieren. Ist das folgende in C# möglich.

C#:
public class Foo {}

public class Bar : Foo {}

public class Foobar : Bar {}

Die Antwort darauf lautet klar ja.

Jetzt bliebe noch die Möglichkeit das mit "Klassen" in der Definition von Mehrfachvererbung nicht so genau zu nehmen und es mit Interfaces zu vermengen. Ist das folgende in C# möglich.

C#:
public class Foo {}

public interface Bar {}

public class Foobar : Foo, Bar {}

Die Antwort darauf lautet auch ja und bildet deinen Code ab.

Hat aber leider alles nichts mit "Mehrfachvererbung" zu tun. Dabei spielt es keine Rolle, ob Interfaces eine
default interface method implementation unterstützen oder nicht. Es ist und bleibt ein Interface.

Vielleicht hilft ja auch ein Zitat aus dem von mir oben gepostete Link, um beide etwas klarer voneinander zu unterscheiden.

Inheritance and an "is a" relationship
...
A class or struct can implement one or more interfaces. While interface implementation is often presented as a workaround for single inheritance or as a way of using inheritance with structs, it is intended to express a different relationship (a "can do" relationship) between an interface and its implementing type than inheritance.

Klassenableitungen vermitteln also eine "Ist eine"-Beziehung und Interfaces eine "Können tun"-Beziehung.

Das einige in der Frage eine Grundsatzdiskussion zur Sinnhaftigkeit von Objektorientieren Sprachkonstrukten sehen, erschließt sich mir nur bedingt. Aber jeder wie er mag.
 
  • Gefällt mir
Reaktionen: ReignInBlo0d, tollertyp, f00bar und 2 andere
Hey efcoyote,

vielen Dank für deine ausführliche und für mich sehr gut nachvollziehbaren Erklärungen! Damit kann ich super im Kopf arbeiten.

Was mir auch gefällt, dass du mich implizit darauf aufmerksam machtest, dass ich in der Tat da eher eine Grundsatzdiskussion anstrengte. Meine Motivation lag einfach darin, dass der Anfangspost in meinen Augen eine ergebnisoffene Fragestellung war ("Meinungen?") und einige Teilnehmer mehrfach nach dem Sinn der Frage bzw. der Verbindung zu "Spassfrage" war und es für mich den Anschein hatte, die Frage somit eher unabsichtlich abzuwürgen. Doch bevor ich schon wieder weiter abgleite, danke dir!

und schönen Tag noch...
 
  • Gefällt mir
Reaktionen: efcoyote
Die Problematik der Unterscheidung zwischen Interfaces und Basisklassen ergibt sich für viele erst in konkreten Anwendungsfällen.

efcoyote schrieb:
Klassenableitungen vermitteln also eine "Ist eine"-Beziehung und Interfaces eine "Können tun"-Beziehung.
Dieser Satz bildet das sehr gut ab.


Grundsätzlich gibt es kein richtig oder falsch bei der Softwareentwicklung, sondern nur Möglichkeiten, die man entweder nutzt oder eben nicht. Dazu zählen nicht nur Interfaces und (abstrakte) Klassen, sondern auch Operatoren, Bibliotheken, dies, das, Ananas. Eine Argumentation auf der Basis "Hab ich nie benutzt und gibt es in Sprache XY nicht, also ist das Schwachsinn" verbietet sich dabei, weil man womöglich nie vor einem Problem stand, bei dem eben gerade diese Möglichkeit doch ganz geil gewesen wäre und zu eleganterem Code hätte führen können - oder man baut es eben anders, was am Ende genauso funktioniert, aber vielleicht in mehr Code resultiert oder einem später womöglich sogar auf die Füße fällt, wenn man etwas erweitert. Und nur weil etwas in anderen Programmiersprachen anders gelöst wurde oder womöglich gar nicht existiert, heißt das nicht, dass es zwangsläufig besser ist - selbst wenn es bei allen anderen Sprachen so wäre.

Man nehme einfach ein beliebiges Problem X, gebe es bei google nebst einer Programmiersprache nach Wahl ein und man findet Dutzende, Hunderte Lösungen dazu, die jeweils andere Techniken einsetzen. Mal Interfaces, mal abstrakte Basisklassen, mal weder das eine noch das andere, mal so, mal so. Die Grenzen verschwimmen dabei zwangsläufig, weil es wie gesagt kein richtig oder falsch gibt, sondern nur einen bunten Strauß an Möglichkeiten.

Wenn man also Interfaces nicht mag und ihren Sinn nicht sieht, nutzt man sie eben nicht. Darüber kann man auch nur schwierig diskutieren, weil man dazu einfach das nächstbeste Programmierhandbuch aufschlagen muss, wo erklärt wird wofür man das braucht bzw. brauchen könnte. Aus den klassischen Beispielen nach dem Motto abstract class Fahrzeug, class Auto:Fahrzeug und IVerbrenner bzw. IElektro wird zwar das Konzept an sich klar, aber wenn man keinen konkreten Anwendungsfall hat, in dem das praktisch wäre, fehlt einem der Blick für den tieferen Sinn dahinter und man beginnt, das Konzept als solches in Zweifel zu ziehen - ohne Blick auf andere, die eben diese Möglichkeiten sehr zu schätzen wissen und auch regelmäßig einsetzen, weil sie Anwendungsfälle haben, in denen es sinnvoll ist.
 
  • Gefällt mir
Reaktionen: Rossibaer, tollertyp, efcoyote und eine weitere Person
Rossibaer schrieb:
@tollertyp: Interessante Sache, dass ich in meinen vorherigen Post explizit nach dem Unterschied von "interface" und "abstract class" fragte, du dann einfach das Wort "abstract" entferntest, was wiederum insgesamt ne Veränderung der Parameter bedeutet, dementsprechend auch besser zu deiner Antwort passte, aber im Kern nichts mehr mit dem zu tun hatte, worauf ich hinaus wollte!
Also damit erspare ich mir jede weitere Diskussion mit dir. Dunning Krueger in Bestform bei dir.
Es spielt für meine Aussage schlicht keine Rolle, ob man von abstrakter Klasse oder von Klasse spricht. Meine Aussagen gelten für beide.
Dein Programmierverständnis reicht offensichtlich nicht aus, um das selbst zu erkennen. Und die Mühe nachzudenken machst du dir scheinbar auch nicht.

Weil jetzt kommt was ganz verrücktes: Jede abstrakte Klasse ist auch eine Klasse. Aber nicht jede Klasse ist eine abstrakte Klasse. Meine Aussage, die ich mir angeblich so zurecht gelegt habe, dass sie passt, galt für alle Klassen.

Ergänzung ()

efcoyote schrieb:
Klassenableitungen vermitteln also eine "Ist eine"-Beziehung und Interfaces eine "Können tun"-Beziehung.
Dem würde ich grundsätzlich beipflichten, auch wenn das keine absolute Regel ist. Aber für viele Fälle gilt es und es ist für ein Klassendesign durchaus eine sinnvolle Basis. Wollte selbst so etwas in der Art schreiben (statt "können tun" hätte ich eben gesagt dass Interfaces eher das Verhalten beschreiben).

Ausnahmen sind z.B. dann, wenn eine API definiert wird.
Ergänzung ()

Raijin schrieb:
Grundsätzlich gibt es kein richtig oder falsch bei der Softwareentwicklung,
außer jemand behauptet er hätte die Mehrfachvererbung für C# erfunden... :p
Ergänzung ()

Micke schrieb:
Sprich es gibt MehrfachVererbung in C#, wenn auch nicht von Klasse zu Klasse.
Wenn du MechfachVererbung umdefinierst dann ja.
Dann gibt es aber auch eine Künstliche Intelligenz in C#. Ich habe den Ausdruck "künstliche Intelligenz" jetzt einfach mal kurz neu definiert für mich und er bedeutet für mich die Möglichkeit, eine Klasse auf mehrere Dateien zuverteilen.
 
Zuletzt bearbeitet:
efcoyote schrieb:
public class Foobar : Foo, Bar {}
Du hast gerufen? :D
SCNR.

Im Endeffekt geht es hier doch nur noch um die Definitionen. efcoyote hat hervorragend dargelegt, wie die aussehen, man kann eigentlich kaum noch etwas hinzufügen. Höchstens, dass Programmiersprachen grundsätzlich von Definitionen und Spezifikationen leben und man diese schon allein deshalb nicht einfach ignorieren kann. Für die konkrete Umsetzung eines Vorhabens ist es doch nach wie vor per se wurscht, wie man vorgeht. Mir persönlich waren Interfaces schon immer lieber als abstrakte Klassen, aber beide haben ihre Daseinsberechtigung. Mir ist bei der ersten leichten Lektüre über C#11 aufgefallen, dass man jetzt auch statische abstrakte Member einbauen kann.

C#:
void CanSwim<T>(T pet) where T : IPet
{
    Console.WriteLine(T.CanSwim);
}

void CanRun<T>(T pet) where T : IPet
{
    Console.WriteLine(T.CanRun);
}

CanRun(new Horse());
CanRun(new Goldfish());

CanSwim(new Horse());
CanSwim(new Goldfish());

public interface IPet
{
    static abstract bool CanRun {  get; }
    static abstract bool CanSwim { get; }
}

public class Horse : IPet
{
    public static bool CanRun => true;
    public static bool CanSwim => true;
}

public class Goldfish : IPet
{
    public static bool CanRun => false;
    public static bool CanSwim => true;
}

In einigen Situationen bedeutet das wahrscheinlich, dass man auf Reflection verzichten könnte, weil man Zugriff auf die statischen Member erhält, ohne deren genauen Typ T kennen zu müssen. Spannende Geschichte, finde ich.
 
  • Gefällt mir
Reaktionen: Micke und tollertyp
Das Beispiel ist semantisch wirklich nicht doll, aber ich hatte keine Lust, hier jetzt ein Codebeispiel mit Metadaten und dem ganzen Zauber zusammenzubasteln - ganz zu Ende bin ich mit dem Gedankengang ehrlicherweise sowieso noch nicht.

Man denke einfach mal an ein MVC-Konstrukt, an Routen. Metadaten konnte man bisher nur mit Reflection anfassen, und was das an Overhead bedeutet, ist bekanntlich nicht zu unterschätzen. Mit diesen statischen abstrakten Membern sollte es möglich sein, sowas wie einen Handler zu bauen, der alle Instanzen eines Interfaces abgreift und beispielsweise Endpunkte registriert, das Ganze ohne Reflection.

Kann sein, dass mir da irgendwas durch die Lappen geht (Kaffee wirkt heute nicht so richtig), aber ich sehe da irgendwie durchaus Potential.
 
  • Gefällt mir
Reaktionen: tollertyp
Der große Vorteil von diesen statischen Sachen ist halt, dass wenn deine Basis-Klasse/Interface eine statische Methode hat, die selbst abstrakte statische Sachen aufruft.

Oder anderes einfaches Beispiel: Zugriff auf einen statischen Logger. Das Interface sagt nur "Ich brauche einen Logger". Ohne statische abstrakte Methoden muss dann halt eine nicht-statische "getLogger" rein, die dann wiederum das statische Feld liefert.
(ich bin eher im Java-Umfeld unterwegs, statt Methode würde man in C# evtl ja auch einfach ne Property machen)
 
Zuletzt bearbeitet:
  • Gefällt mir
Reaktionen: f00bar
Status
Für weitere Antworten geschlossen.
Zurück
Oben