it-swarm.com.de

Schnittstellen in Java instanziieren

Ich habe diese Schnittstelle:

public interface Animal {
    public void Eat(String name);
}

Und dieser Code hier implementiert die Schnittstelle:

public class Dog implements Animal {
    public void Eat(String food_name) {
        System.out.printf(food_name);
    }

    public static void main(String args[]) {
        Animal baby2 = new Dog(); //HERE!!!!!!!!!!!!!!!!!!!!!!
        baby2.Eat("Meat");
    }
}

Meine Frage ist, warum funktioniert der Code? Eine Schnittstelle kann nicht instanziiert werden. In diesem Fall wurde die Schnittstelle jedoch instanziiert (mit dem Kommentar "HIER !!!!!!!!!!!!!").

Was passiert hier?

20
user1535147

Nein, das ist es nicht - Sie instantiieren ein Dog, aber da ein Dog ein Animal ist, können Sie die Variable zu einem Animal erklären. Wenn Sie versuchen, die Schnittstelle Animal zu instanziieren, wäre dies:

Animal baby2 = new Animal();

Versuchen Sie das und sehen Sie, wie der Compiler entsetzt schreit :)

34
Ziyao Wei

Dog ist keine Schnittstelle: Dog ist eine class that implementiert die Animal-Schnittstelle.

Hier ist nichts Unangenehmes los.


Beachten Sie, dass Sie eine anonyme Implementierung einer Schnittstelle wie folgt instanziieren können:

Animal animal = new Animal() {
    public void Eat(String food_name) {
        System.out.printf("Someone ate " + food_name);
    }
};
17
Bohemian

Betrachten wir den folgenden Code:

interface Cookable {
    public void cook();
}

class Food {
    Cookable c = new Cookable() {
     public void cook() {
         System.out.println("anonymous cookable implementer");
        }
      };
 }

Der vorstehende Code erstellt eine Instanz einer anonymous inner-Klasse, aber hier ist die neue Just-in-Time-Klasse ein Implementierer der Cookable - Schnittstelle. Beachten Sie, dass dies die einzige Zeit ist, in der Sie die Syntax jemals sehen werden:

new Cookable()

dabei ist Cookable eine Schnittstelle und kein nicht abstrakter Klassentyp. Denken Sie darüber nach: Sie können eine Schnittstelle nicht instanziieren, aber so sieht der Code aus. Natürlich instanziiert es keinen Cookable object-- es erstellt eine Instanz eines neuen anonymous implementer of Cookable

Sie können diese Zeile lesen:

   Cookable c = new Cookable(){}

als "Deklarieren Sie eine Referenzvariable vom Typ Cookable, die offensichtlich auf ein Objekt einer Klasse .__ verweist, die die Schnittstelle Cookable implementiert. Aber, oh ja, wir haben noch keine Klasse .__ das implementiert Cookable, also machen wir hier gleich einen richtigen Wir brauchen keinen Namen für die Klasse, aber es wird eine Klasse sein, die Cookable implementiert, und diese geschweifte Klammer startet die Definition der neuen implementierenden Klasse. "

Wichtig für anonyme Schnittstellenimplementierer - Sie können nur eine Schnittstelle implementieren. Es gibt einfach keinen Mechanismus, der besagt, dass Ihre anonyme innere Klasse mehrere Schnittstellen implementieren wird. In der Tat kann eine anonyme innere Klasse nicht einmal eine Klasse erweitern und gleichzeitig eine Schnittstelle implementieren. Die innve-Klasse muss entweder eine Unterklasse einer benannten Klasse sein und keine Schnittstelle direkt implementieren oder eine einzelne Schnittstelle implementieren.

Lassen Sie sich also nicht von irgendwelchen Versuchen täuschen, eine Schnittstelle zu instanziieren, außer im Fall einer anonymen inneren Klasse. Folgendes ist nicht legal:

Runnable r = new Runnable(); // can't instantiate interface 

in der Erwägung, dass Folgendes zulässig ist, da es einen Implementierer der Runnable-Schnittstelle (eine anonyme Implementierungsklasse) instantiiert:

Runnable r = new Runnable() { 
   public void run(){ }
};

Sie können meinen Artikel hier lesen.

10
Setu Basak

Was Sie hier beobachten, ist der Abhängigkeitsinversion Aspekt von SOLID .

Ihr Code hängt von der Abstraktion des Animal-Vertrages ab, indem eine konkrete Implementierung davon erstellt wird. Sie geben lediglich an: "Ich mache ein irgendein Objekt, aber unabhängig davon, was dieses Objekt tatsächlich ist, ist es an den Vertrag der Animal-Schnittstelle gebunden."

Nehmen Sie zum Beispiel diese Art von Erklärungen:

List<String> wordList = new LinkedList<>();
Map<Integer, String> mapping = new HashMap<>();

In beiden Fällen besteht der Hauptaspekt der Liste und der Karte darin, dass sie dem generischen Vertrag für eine List und eine Map folgen. 

7
Makoto
Animal baby2 = new Dog(); //HERE!!!!!!!!!!!!!!!!!!!!!!

Sicher instanziieren Sie das Tier nicht. Sie referenzieren nur die Dog-Instanz darauf ..__ In Java können wir die Superklassenreferenz nehmen.

2
John

Wenn du sagst:

Animal baby2 = new Dog();

der Referenztyp ist Animal (die Schnittstelle), der auf konkrete Implementierungen (Dog) verweist. Der Objekttyp Hund ist konkret und kann instanziiert werden. In diesem Fall, solange der Hund einen Nullpunkt mit dem Hund hat. Eine konkrete Implementierung aller Methoden in der Schnittstelle können Sie als Referenztyp festlegen 

Wenn du etwas getan hast,

Animal baby2 = new Animal(); // here you are actually instantiating

dies wäre ungültig, da Sie nun versuchen, aus einer abstrakten Implementierung ein konkretes Objekt zu erstellen.

1
user3397207

Um ein breiteres Bild zu haben:

Animal [] Zoo = new Animal[10] ; // is also correct

aber warum ?

Die ganze Idee ist, dass Sie in der obigen Tabelle 10 Tiere verschiedener Typen einstellen können. Voraussetzung dafür ist, dass alle Tiere, die den Zoo betreten, die Schnittstelle Animal implementieren müssen. 

public interface Animal {
 void Eat();
}
class Wolf implements Animal {  void Eat (){ 
System.out.println("Wolf eats meat ") ;}}

Class Zebra implements Animal{ void Eat (){
System.out.println("Zebra eats the grass ") ;}}

class test {
public static void main (String args []) {

Animal [] Zoo = new Animal[2] ;

Zoo[0] =  new Wolf() ;
Zoo[1] = new Zebra() ;

 //so you can feed your animals in Zoo like this

 for (int i=0 ; i<Zoo.lenght;i++) {Zoo[i].Eat();}
}
}
1
Java Main

Dies ist ein Fall von Polymorphismus. Es sieht so aus, als ob Sie ein Tierobjekt erstellen, aber nicht. Sie erstellen ein "Dog" -Objekt, das zur Laufzeit berechnet wird. "Tier" fungiert als Vertrag. Die Schnittstelle kann nicht direkt instanziiert werden, kann jedoch als Typ verwendet werden, indem die Unterklasse aktualisiert wird. Sie können auch eine anonyme Klasse verwenden, um ein Objekt als 'Animal'-Typ zu instanziieren.

   Animal baby2 = new Dog(); //upcasting polymorphically
   Animal baby3=new Animal(){
      public void Eat(String food){System.out.println("fdkfdfk"); }
   }
    //You can instantiate directly as anonymous class by implementing all the method of interface
1

Das Interface Animal fungiert als Datentyp für die Klasse Dog. Sie instanziieren tatsächlich die Dog-Klasse, nicht die Schnittstelle oder deren Datentyp. 

1
Beaumont Muni

Die Schnittstelle Animal wird nicht instanziiert, sondern von Dog implementiert. Und Dog wird initiiert 

1
BlackJoker

Eigentlich können Sie die Schnittstelle instanziieren. Hier ist der Code, den Sie ausprobieren können

public static void main(String args[]) {
    System.out.println(new Animal() {
        public String toString() {
            return "test";
        }
    });
}

Dieses Programm wird erfolgreich ausgeführt und test.__ ausgegeben. Versuchen Sie es.

0
Amol Dixit

Hier wird nur auf die Schnittstelle verwiesen, aber die Instantiierung wird nur von der Klasse ausgeführt

Animanl a = new Dog Animal a - Variable wird referenziert

0
sanjil