Instantiierung von Interfaces



  • Hi,

    ich habe grade folgenden Source in einem Buch gefunden, der angeblich nicht funktionieren soll:

    using System;
    
    public interface ILaufen {
       void Laufe();
       double GetGeschwindigkeit();
    }
    
    public class ImplKlasse : ILaufen {
       public ImplKlasse() {
       }
       public void Laufe() {
       }
    
       public double GetGeschwindigkeit() {
          return 2.0;
       }
    }
    
    public class Test {
       public static void Main() {
          ImplKlasse obj = new ImplKlasse();
          ILaufen il = new ImplKlasse();    // Das soll angeblich nicht gehen
          Console.Read();
       }
    }
    

    Irgendwie erschien mir das komisch. In Java würde das ja auch gehen und ich sehe absolut keinen Grund, warum das nicht gehen sollte. Kompilieren lässt es sich auch problemlos. Habe ich was übersehen oder steht in dem Buch Müll?



  • Es geht grundsätzlich schon. Bei einem Interface handelt es sich nach Definition um eine Klasse. Es bleibt nur die Frage, WAS du mit einem Intanzierten Interface denn so anstellen möchtest. Ein Interface muss eigentlich immer in eine Klasse implementiert werden.

    public class MeineKlasse : ILaufen
    {
    //irgendein Code
    }
    

    Du wirst mit einem intanzierten Interface nichts mehr anstellen können. Ein Interface bietet dir die Möglichkeit, bei unterschiedlichen Methoden/Feldern in der Klasse, gleiche Schnittstellen anzubieten.

    Aber eine instanzierte Schnittstelle kannste ja nirgends mehr Implementieren Bzw. hast du schonmal versucht von einer instanzierten Klasse zu erben ?

    Mir fällt dazu gar kein Beispiel ein, welches man dazu benutzen könnte.

    Also wie gesagt, du kannst Schnittstellen bestimmt instanzieren (habs aber noch nicht versucht), da es sich ja um Klassen handelt (die nicht statisch sind). Aber die Frage ist. WAS bringt es Dir?

    Eine Klasse die ein Interface implementiert, ERBT die Schnittstellen. Somit stehen sie der Klasse zur Verfügung. Jeder andere Klasse, welche das Interface implementiert, hat nun sein Eigenes Interface, womit sich die Instanzierung eines Interfaces, im Sinn, wieder aufhebt.

    Gruß

    Markus Seidl

    P.S. @Community, ich hoffe ich habe es richtig beschrieben. Ich lese zurzeit ein Buch, indem ich die Auffassung zu Interfaces wie oben beschrieben hatte.



  • Irgendwie hat mir dein Beitrag nicht wirklich geholfen.
    Dir ist schon klar, dass man ein Interface selbst überhaupt nicht instantiieren kann? Ich habe den Titel nur gewählt, weil "Objekt einer Klasse, das ein Interface implementiert, instantiieren und einer Referenzvariablen vom Typ des Interfaces zuweisen" zu lange war. Ich habe mich einfach gewundert, dass der Autor behauptet, dass so etwas nicht geht:

    Interface i = new KlasseDieDasInterfaceImplementiert();
    

    Er meinte, es ginge in C# nur so:

    Interface i = ((new KlasseDieDasInterfaceImplementiert()) as Interface);
    


  • Ups Sorry, hab ich mich vertan, ich bin nachdem Titel gegangen und bin über den Quellcode rübergehuscht.

    Trotzdem, versuchst du doch das Interface zu Instanzieren, aus der Klasse, die das schon implementiert hat, oder nicht?

    Du versuchst ja mit der Zeile

    Interface i = ((new KlasseDieDasInterfaceImplementiert()) as Interface);
    

    das Interface zu instanzieren.

    Und Warum du das mit dem anhängsel as Interface machen musst, kann ich mir gut vorstellen.

    new KlasseDieDasInterfaceImplementiert() gibt dir doch die ganze Klasse. Und du willst ja schließlich NUR das Interface, oder nicht? Warum der der Compiler allerdings dann keinen Fehler bringt verstehe ich nicht. Da die Zeile mit dem New Operator sicherlich keine Interface zurückgibt 😕

    Gruß

    Markus Seidl



  • der cast is quatsch; das geht auch ohne.
    analog zu java und c++ (und zich anderen sprachen wahrscheinlich auch).



  • Angren Aldaron schrieb:

    Ups Sorry, hab ich mich vertan, ich bin nachdem Titel gegangen und bin über den Quellcode rübergehuscht.

    Trotzdem, versuchst du doch das Interface zu Instanzieren, aus der Klasse, die das schon implementiert hat, oder nicht?

    Du versuchst ja mit der Zeile

    Interface i = ((new KlasseDieDasInterfaceImplementiert()) as Interface);
    

    das Interface zu instanzieren.

    Nein. Ich instantiiere eine Klasse, die das Interface implementiert. Das ist ein Unterschied!

    Und Warum du das mit dem anhängsel as Interface machen musst, kann ich mir gut vorstellen.

    Ich nicht und ich sehe auch keinen Sinn darin.

    new KlasseDieDasInterfaceImplementiert() gibt dir doch die ganze Klasse.

    ? Das gibt mir eine Referenz auf die Klasse.

    Und du willst ja schließlich NUR das Interface, oder nicht? Warum der der Compiler allerdings dann keinen Fehler bringt verstehe ich nicht. Da die Zeile mit dem New Operator sicherlich keine Interface zurückgibt 😕

    ???



  • entelechie schrieb:

    der cast is quatsch; das geht auch ohne.
    analog zu java und c++ (und zich anderen sprachen wahrscheinlich auch).

    Gut! Dann ist das Buch Schrott 👎
    Dann finde ich jetzt eigentlich nur noch die Arrays in C# hässlich 😉



  • War zu spät dran. OK du instanzierst ganz normal eine Klasse. Danke!!!



  • wenn man von einer instanz der klasse nur eine referenz auf das interface hat, dann kann man nur die methoden aufrufen, die im interface definiert sind. so kann man von verschiedenen objekten nur die interfaces ansprechen, was sie in gewissen situationen einheitlich aussehen lässt. man schränkt sich damit also ein, für was immer das gut ist.



  • AZOOO, ich nehme NUR die Referenz auf das Interface, um nur diese Methoden, bzw. Variablen dieses, in der Klasse implementierten, Interfaces hernehmen zu können. Und sonst keine. Daher auch das mit dem "Interface i =..."

    Das heißt, man beschränkt sich selbst nur auf das Interface. Wäre es nicht genauso gut mit den Modifikatoren private und protected zu arbeiten? Also eben alle Methoden und Felder der Klasse als private zu deklarieren und das Interface als public.

    Müsste doch dann den gleichen Effekt haben? Denn dann kann ich doch auch nur noch auf das Interface zugreifen.

    Gruß

    Markus Seidl



  • Angren Aldaron schrieb:

    Das heißt, man beschränkt sich selbst nur auf das Interface. Wäre es nicht genauso gut mit den Modifikatoren private und protected zu arbeiten? Also eben alle Methoden und Felder der Klasse als private zu deklarieren und das Interface als public.
    Müsste doch dann den gleichen Effekt haben? Denn dann kann ich doch auch nur noch auf das Interface zugreifen.

    ääääh jein...
    die methoden eine interfaces sollten immer public o.ä sein. ist in java, glaube ich, per default so. in c# bestimmt auch (ist ja von java abgekupfert)



  • net schrieb:

    Angren Aldaron schrieb:

    Das heißt, man beschränkt sich selbst nur auf das Interface. Wäre es nicht genauso gut mit den Modifikatoren private und protected zu arbeiten? Also eben alle Methoden und Felder der Klasse als private zu deklarieren und das Interface als public.
    Müsste doch dann den gleichen Effekt haben? Denn dann kann ich doch auch nur noch auf das Interface zugreifen.

    ääääh jein...
    die methoden eine interfaces sollten immer public o.ä sein. ist in java, glaube ich, per default so. in c# bestimmt auch (ist ja von java abgekupfert)

    Japp. Wenn du die Methoden eines Interfaces nicht explizit definierst, müssen sie public sein. Is ja auch logisch.



  • Also ob die Methoden öffentlich sein sollen, ist wohl eher Anwendungsfall, aber im Grunde hatte ich doch recht, oder nicht. Ihr macht das mit dem Instanzieren des Interfaces der Klasse doch nicht anders.

    Gruß

    Markus Seidl

    PS: Und Java ist ebenfalls wieder irgendwo abgekupfert. Is aber normal. Man behält was gut ist, und tauscht aus was schlecht ist. Innovation. In Novus. Nicht Neu. Nicht KOMPLETT neu



  • Angren Aldaron schrieb:

    Also ob die Methoden öffentlich sein sollen, ist wohl eher Anwendungsfall

    Ich glaub du verstehst nicht ganz: Die Sichtbarkeit von Methoden, die du aus einem Interface implementierst MÜSSEN public sein (mal abgesehen von der von mir oben dargelegten Ausnahme).

    PS: Und Java ist ebenfalls wieder irgendwo abgekupfert. Is aber normal. Man behält was gut ist, und tauscht aus was schlecht ist. Innovation.

    Eher Evolution 🙂



  • interpreter schrieb:

    entelechie schrieb:

    der cast is quatsch; das geht auch ohne.
    analog zu java und c++ (und zich anderen sprachen wahrscheinlich auch).

    Gut! Dann ist das Buch Schrott 👎
    Dann finde ich jetzt eigentlich nur noch die Arrays in C# hässlich 😉

    Was stört dich an denen? Gibt sogar mehrdimensionale, die würde ich mir für Java wünschen. Stattdessen kommt dann so ein Schwachsinn: http://www.jcp.org/en/jsr/detail?id=83

    Jojo, über die Verbohrtheit, mal an der Sprache was zu verbessern, kann ich wirklich nur staunen. 🙄



  • Optimizer schrieb:

    interpreter schrieb:

    entelechie schrieb:

    der cast is quatsch; das geht auch ohne.
    analog zu java und c++ (und zich anderen sprachen wahrscheinlich auch).

    Gut! Dann ist das Buch Schrott 👎
    Dann finde ich jetzt eigentlich nur noch die Arrays in C# hässlich 😉

    Was stört dich an denen? Gibt sogar mehrdimensionale, die würde ich mir für Java wünschen. Stattdessen kommt dann so ein Schwachsinn: http://www.jcp.org/en/jsr/detail?id=83

    Jojo, über die Verbohrtheit, mal an der Sprache was zu verbessern, kann ich wirklich nur staunen. 🙄

    Findest du so etwas schön:
    foo[][,,,][,] bar;

    Generell finde ich diese Schreibweise mit den Kommata sehr ungewohnt. Im Großen und Ganzen gefällt mir die Sprache dennoch sehr 🙂



  • foo[][,,,][,] bar;

    Leichte Übertreibung, oder? Wofür brauchst du ein Array von 4dimensionalen Arrays von 2dimensionalen Arrays?

    Fakt ist doch, dass man häufig solchen Code hat.

    int[][] myArray;
    

    Jetzt kann man das Ganze rechteckig machen (dass das in C# nur über Umwege geht, ist wohl Absicht). Ich könnte aber jetzt z.B. dem foo[3] ein Array mit Länge 5 zu weisen und dem foo[4] eins mit Länge 31. Allein schon, weil man das aber so selten braucht, finde ich es sinnvoll, mehrdimensionale Arrays anzubieten und nicht nur "Arrays von Arrays".
    Man kann jetzt einfach ein mehrdimensionales Array erstellen, das schaut doch auch nicht schlechter aus.

    int[,]
    

    Jetzt ist aber klar, dass dieses Array immer "rechteckig" ist. Das gibt dem JIT-Compiler zusätzliche Möglichkeiten zur Optimierung, es ist für den Programmierer klarer, dass es sich um ein rechteckiges Feld handelt. Wenn meine Methode Arrays vom Typ foo[,] annimmt, dann ist sichergestellt, dass das Array rechteckig ist. Es ist immer gut, wenn man dem Compiler möglichst genau sagen kann, was man machen will.



  • interpreter schrieb:

    Angren Aldaron schrieb:

    Also ob die Methoden öffentlich sein sollen, ist wohl eher Anwendungsfall

    Ich glaub du verstehst nicht ganz: Die Sichtbarkeit von Methoden, die du aus einem Interface implementierst MÜSSEN public sein (mal abgesehen von der von mir oben dargelegten Ausnahme).

    Öhmmmmmm...... Ja........ natürlich müssen die öffentlich sein, habe aber auch nie was anderes behauptet. Vielleicht mein Fehler, dass es falsch verstanden wurde. Ich meinte nie die Methoden aus dem Interface, sondern die aus der Klasse. Sorry für das Missverständniss. War mir von Anfang an klar, dass wenn man ein Interface hat, die Dinger natürlich öffentlich sein müssen. Mach ja sonst wirklich keinen Sinn.

    Was ich eigentlich meinte: Ich beschränke mich selbst damit, dass ich nur die Referenz auf das Interface einer Klasse nehme.

    Weiterhin meinte ich eigentlich: Es wäre doch das gleiche, wenn ich da nix instanziere/referenziere (meinetwegen auch gebäre), sondern die Klasse mit den Interface erstmal so lasse, und die Methoden innerhalb der Klasse (nix Interface) alle auf private setze, meinetwegen auch protected, damit die gebärten Klassen auch noch darauf zugreifen können.

    Denn dann könnte ich ja immer noch über das Interface (dessen Methoden und Variablen auf Public sind), auf die Private Methoden der Klasse zugreifen.

    Ich hoffe ich konnte jetzt damit alle Missverständnisse aus der Welt schaffen. Sorry wenn ich mich nicht immer ganz klar Ausdrücke. Bin noch am lernen. Ich hab mir jetzt dafür einen 954 Seiten Schinken geholt. Vielleicht kennt das einer. "Visual C# - Grundlagen, Programmiertechniken, Windows-Programmierung" (von Frank Eller und Michael Kofler) Bin bis jetzt zufrieden und selbst das mit den Events habe ich langsam mit dem Buch raus.

    Also Sorry Community, wenn ich dir Aufgrund meiner Unwissenheit auf die Nerven gehe. Dies ist allerdings meine erste Sprache, bei der ich mal wirklich versuche, mich einzuarbeiten.

    Gruß

    Markus Seidl



  • mhm, aber der sinn dabei, klasseninstanzen interfacereferenzen zuzuweisen, besteht ja nicht darin, sich möglichst viel einzuschränken. (das würde man dann wirklich über private-deklarationen lösen, wie du gesagt hast) der sinn besteht ja aber eher darin, dass man objekte ganz unterschiedlicher klassen, die aber das gleiche interface implementieren in der selben referenzvariablen speichern kann, wenn man dann sowieso nur methoden aus dem interface ausführen will. das hat oft vorteile.



  • Jop. Eine Klasse, die das Interface implementiert , ist vom Typ [Interface].
    Damit wird versucht, Mehrfachvererbung ohne die üblichen Nachteile nachzubilden.
    Ich kann ein Auto und ein Haus Objekt haben. Wenn sie beide vom Typ "ICompareable" sind, kann ich sie vergleichen und sortieren.

    Letzlich kann man das Implementieren von Interfaces auch als Vererbung betrachten, denn nichts anderes ist es. Es können über diesen Weg nur keine Implementierungen vererbt werden, sondern eben nur die Schnittstelle (warum das Ding wohl Interface heißt?).


Log in to reply