2016-06-18 8 views
11

Ich weiß, was die Implementierung einer Schnittstelle bedeutet (technisch), aber ich bin mir nicht sicher, ob ich verstehe, was der "Vertrag" umfasst:Muss eine Klasse sich an den dokumentierten Vertrag einer Schnittstelle halten, um diese Schnittstelle zu implementieren

Lets sagen, ich mache eine Klasse MyList, die java.util.List implementiert (das heißt, ich implementiere alle Methoden mit Code, der kompiliert), ist MyList ein List dann? ODER muss ich alle Kommentare der Methoden, die ich außer Kraft setze, lesen und sicherstellen, dass meine Implementierung diese "Erwartung" bezüglich des Verhaltens erfüllt?

+0

Ist MyList eine Liste? Ja – Enzokie

+0

@Enzokie Also würde ich 'add' implementieren, um nichts zu tun, und' bekomme', um immer null zurückzugeben, würden Sie es immer noch eine Liste nennen? –

+0

Solange Sie die Liste implementieren, wird sie immer noch als Liste bezeichnet. Am Ende des Tages ist es Ihre Entscheidung, ob Sie etwas auf diese implementierten Methoden setzen oder eine Unsupported Exception werfen, die Tatsache, dass es immer noch eine Liste genannt wird. – Enzokie

Antwort

12

Technisch ja, MyList ist ein List, wenn es alle Methoden der List Schnittstelle implementiert. Aber der Compiler ist kein Magier. Es kann nicht überprüfen, ob Ihre Methoden das tun, was sie tun sollen. Und natürlich sollte jede Methode tun, was ihre Dokumentation sagt.

Wenn ich erhalten eine List und diese List ist eine Instanz MyList, und ich rufe list.add("foo"), ich „foo“ erwarten am Ende der Liste hinzugefügt werden. Nicht entfernt werden, oder zweimal hinzugefügt werden, oder was auch immer anderes Verhalten. Wenn also Ihre Klasse List implementiert, sollten ihre Methoden mit dem in der API-Dokumentation definierten Vertrag übereinstimmen.

Stellen Sie sich vor, Sie verkaufen Autos. Ich gehe zu deinem Geschäft und kaufe ein Auto. Für mich ist es ein Auto, weil es wie alle anderen Autos aussieht: Es hat Räder, Pedale, Fenster usw. Aber wenn ich auf das Gaspedal drücke, bremst es, und wenn ich das Licht einschalte, hupt es, und wenn ich das öffne Fenster, es beschleunigt und tötet ein armes Kind auf der Straße, ich werde überhaupt nicht glücklich sein und Sie werden in Schwierigkeiten sein, weil das Auto, das Sie mir verkauft haben, sich nicht richtig verhält.

+0

Haha gutes Beispiel +1 – rpax

+0

Also gibt es keinen formellen Weg zu sagen, ob meine Implementierung "richtig" oder "falsch" ist, es klingt ziemlich vage, es geht alles um (informelle) Erwartungen. Es wäre schön, wenn interface/abstract class mit einem Unit-Test kommt, der entscheidet, ob die implementierende Klasse alle Erwartungen erfüllt. Derzeit könnte sich die API-Dokumentation ändern, wodurch meine Implementierung plötzlich ungültig wird (ohne mein Wissen). –

+0

Das JDK bietet keinen solchen Komponententest. Es liegt an Ihnen, es zu implementieren. Aber der Vertrag wird sich nie ändern: Das würde den gesamten vorhandenen Java-Code außer Kraft setzen. Die Implementierung einer Standardsammlung ist keine allgemeine Aufgabe. Das JDK und allgemeine Bibliotheken wie Guava bieten alles, was Sie für 99,999% der Anwendungsfälle benötigen. Ich kann nicht Remamber einmal in meinen 20 Jahren Java-Programmierung eine Standard-Sammlung implementiert haben. –

2

In Java besteht der Unterschied zwischen einer Klasse und einer Schnittstelle darin, dass eine Klasse über Methodenimplementierungen verfügt. Eine Schnittstelle nicht. Eine Schnittstelle kann also eine add() -Methode haben, würde aber nichts darüber sagen, wie add funktioniert. Eine Klasse müsste definieren, wie add funktioniert.

Sie implementieren eine Schnittstelle, sobald Sie implements InterfaceName in Ihre Klassendefinition eingeben. Sie müssen dann alle Methoden der Schnittstelle definieren oder Ihre App wird nicht kompiliert. Dann wäre es richtig zu sagen, dass MyClass ein MyInterface ist - Sie könnten sogar MyInterface interface = new MyClass();

Und ja, Sie sollten alle Kommentare lesen und sicherstellen, dass Ihre Klasse die Schnittstelle in der erwarteten Weise implementiert. Sonst wirst du mit etwas enden, das kompiliert, aber möglicherweise nicht richtig funktioniert.

+0

nein, java.util.List ist keine Klasse –

+0

Das behoben, bevor Sie überhaupt gepostet :) –

+1

Uh..java 8+ ermöglicht die Implementierung auf der Schnittstelle. Begrenzt, aber ist möglich. – rpax

1

Die Schnittstelle ist ein notwendiges Minimum für den Vertrag: wie Sie sagen, wenn es nicht kompiliert, können Sie den Vertrag nicht erfüllt haben! Die Sprache ist jedoch möglicherweise nicht in der Lage, die vollständigen Anforderungen der Schnittstelle zu definieren und einzuschränken, daher sollten Sie diese Erwartungen ebenfalls beachten.

Ein einfaches Beispiel ist die ICloneable Schnittstelle. Wenn alles, was Sie tun, implementieren

public MyObject clone() { 
    return (MyObject)super.clone(); 
} // clone() 

dann haben Sie die Sprache Vertrag und vielleicht auch Ihre Klasse Vertrag erfüllt. Aber wenn Ihre Klasse eine List enthält, dann werden Sie Ihre Benutzer überraschen: "Das hat nicht clone() richtig gemacht!"

Der Vertrag enthält auch die Erwartungen der Benutzer. Brechen Sie sie, und obwohl ein Anwalt der Sprache sagen kann, dass Ihre Klasse ein List ist, werden andere nicht zustimmen.

+0

Was ist die 'ICloneable'-Schnittstelle, von der Sie sprechen? [java.lang.Cloneable] (https://docs.oracle.com/javase/8/docs/api/java/lang/Cloneable.html) ist eine marker-Schnittstelle und zwingt Sie nicht einmal dazu, 'clone () '. Aber Sie haben Recht, Marker-Schnittstellen ([Serializable] (https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html) wäre ein weiteres beliebtes Beispiel) existieren nur als eine Art von Versprechen, den Vertrag zu erfüllen - es ist trivial, eine Implementierung zu kompilieren, aber ohne auch den Vertrag zu erfüllen, ist es nutzlos. – Hulk

0

ist MyList eine Liste?

Um diese Frage zunächst, welche Schnittstellen verstehen beantworten müssen, tun oder was sie geschrieben für ...

Dont Schnittstellen vergessen können Sie eine sehr wichtige Abteilung bieten zwischen dem, was eine Klasse kann tun und wie sie es tun ... so technisch eine Schnittstelle implementiert ist nicht zu fragen, ob ein Objekt ist etwas aber mehr über zu fragen, wie ein Objekt etwas tun kann

Wenn Sie also sagen, List myContainer = new ArrayList(); Sie ein Objekt definieren, das alle Dinge eine Liste tun können, tun können ... Hinzufügen, Entfernen, bekommen etc etc

man sagen kann, es eine Liste es, würde ich sagen, dass es tun kann, was eine Liste tun ..