WARUM SCHNITTSTELLE ??????
Es beginnt mit einem Hund. Insbesondere ein Mops .
Der Mops hat verschiedene Verhaltensweisen:
public class Pug {
private String name;
public Pug(String n) { name = n; }
public String getName() { return name; }
public String bark() { return "Arf!"; }
public boolean hasCurlyTail() { return true; } }
Und Sie haben einen Labrador, der auch eine Reihe von Verhaltensweisen hat.
public class Lab {
private String name;
public Lab(String n) { name = n; }
public String getName() { return name; }
public String bark() { return "Woof!"; }
public boolean hasCurlyTail() { return false; } }
Wir können einige Möpse und Labore machen:
Pug pug = new Pug("Spot");
Lab lab = new Lab("Fido");
Und wir können uns auf ihr Verhalten berufen:
pug.bark() -> "Arf!"
lab.bark() -> "Woof!"
pug.hasCurlyTail() -> true
lab.hasCurlyTail() -> false
pug.getName() -> "Spot"
Nehmen wir an, ich betreibe einen Hundezwinger und muss alle Hunde, die ich unterbringe, im Auge behalten. Ich muss meine Möpse und Labradore in separaten Arrays aufbewahren :
public class Kennel {
Pug[] pugs = new Pug[10];
Lab[] labs = new Lab[10];
public void addPug(Pug p) { ... }
public void addLab(Lab l) { ... }
public void printDogs() { // Display names of all the dogs } }
Dies ist aber eindeutig nicht optimal. Wenn ich auch einige Pudel unterbringen möchte , muss ich meine Kennel-Definition ändern, um eine Reihe von Pudeln hinzuzufügen. Tatsächlich brauche ich für jede Art von Hund ein separates Array.
Einsicht: Sowohl Möpse als auch Labradore (und Pudel) sind Hundetypen und haben das gleiche Verhalten. Das heißt, wir können (für die Zwecke dieses Beispiels) sagen, dass alle Hunde bellen können, einen Namen haben und möglicherweise einen lockigen Schwanz haben oder nicht. Wir können eine Schnittstelle verwenden, um zu definieren, was alle Hunde tun können, aber es den spezifischen Hundetypen überlassen, diese bestimmten Verhaltensweisen zu implementieren. Die Benutzeroberfläche sagt "hier sind die Dinge, die alle Hunde tun können", sagt aber nicht, wie jedes Verhalten gemacht wird.
public interface Dog
{
public String bark();
public String getName();
public boolean hasCurlyTail(); }
Dann ändere ich die Mops- und Laborklassen leicht, um das Hundeverhalten zu implementieren. Wir können sagen, dass ein Mops ein Hund und ein Labor ein Hund ist.
public class Pug implements Dog {
// the rest is the same as before }
public class Lab implements Dog {
// the rest is the same as before
}
Ich kann Pugs and Labs immer noch wie zuvor instanziieren, aber jetzt bekomme ich auch einen neuen Weg, dies zu tun:
Dog d1 = new Pug("Spot");
Dog d2 = new Lab("Fido");
Dies besagt, dass d1 nicht nur ein Hund ist, sondern speziell ein Mops. Und d2 ist auch ein Hund, speziell ein Labor. Wir können die Verhaltensweisen aufrufen und sie funktionieren wie zuvor:
d1.bark() -> "Arf!"
d2.bark() -> "Woof!"
d1.hasCurlyTail() -> true
d2.hasCurlyTail() -> false
d1.getName() -> "Spot"
Hier zahlt sich die zusätzliche Arbeit aus. Die Kennel-Klasse wird viel einfacher. Ich benötige nur ein Array und eine addDog-Methode. Beide funktionieren mit jedem Objekt, das ein Hund ist. Das heißt, Objekte, die die Dog-Schnittstelle implementieren.
public class Kennel {
Dog[] dogs = new Dog[20];
public void addDog(Dog d) { ... }
public void printDogs() {
// Display names of all the dogs } }
So verwenden Sie es:
Kennel k = new Kennel();
Dog d1 = new Pug("Spot");
Dog d2 = new Lab("Fido");
k.addDog(d1);
k.addDog(d2);
k.printDogs();
Die letzte Aussage würde anzeigen: Spot Fido
Über eine Schnittstelle können Sie eine Reihe von Verhaltensweisen angeben, die alle Klassen, die die Schnittstelle implementieren, gemeinsam nutzen. Folglich können wir Variablen und Sammlungen (z. B. Arrays) definieren, die nicht im Voraus wissen müssen, welche Art von spezifischem Objekt sie enthalten, sondern nur Objekte, die die Schnittstelle implementieren.