example - using interfaces java
Instanciando interfaces en Java (12)
Este es un caso de polimorfismo. Parece que está creando un objeto ''Animal'' pero no lo está. Está creando un objeto ''Perro'' que se calcula en tiempo de ejecución. ''Animal'' actúa como contrato. La interfaz no se puede instanciar directamente, pero se puede usar como tipo mediante la actualización de su subclase. También puede usar una clase anónima para instanciar un objeto como tipo "Animal".
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
Tengo esta interfaz:
public interface Animal {
public void Eat(String name);
}
Y este código aquí implementa la interfaz:
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");
}
}
Mi pregunta es, ¿por qué funciona el código? Una interfaz no puede ser instanciada. Sin embargo, en este caso, la interfaz fue instanciada (marcado con el comentario "AQUÍ !!!!!!!!!!!!!").
¿Que está sucediendo aquí?
La interfaz Animal
no se integrará sino que será implementada por Dog
. Y se integrará un Dog
Lo que está observando aquí es el aspecto de inversión de Dependencia de SOLIDO .
Su código depende de la abstracción del contrato Animal
al crear una implementación concreta del mismo. Simplemente estás diciendo: "Estoy instalando algún objeto, pero independientemente de lo que ese objeto sea en realidad, estará vinculado al contrato de la interfaz de Animal
".
Tomemos, por ejemplo, este tipo de declaraciones:
List<String> wordList = new LinkedList<>();
Map<Integer, String> mapping = new HashMap<>();
En ambos casos, el aspecto principal de la lista y el mapa es que siguen el contrato genérico para una List
y un Map
.
No, no lo es, estás instanciando un Dog
, pero como un Dog
es un Animal
, puedes declarar que la variable es un Animal
. Si intentas crear una instancia de la interfaz Animal
sería:
Animal baby2 = new Animal();
Pruébalo y mira el compilador gritar de horror :)
Cuando tu dices:
Animal baby2 = new Dog();
el tipo de referencia es Animal (la interfaz) que apunta a implementaciones concretas (Perro). El tipo de objeto Dog es concreto y puede crearse una instancia. En este caso, siempre que Dog tenga un punto animal en Dog. una implementación concreta de todos los métodos en la interfaz, puede hacer un tipo de referencia de
Si hiciste algo como,
Animal baby2 = new Animal(); // here you are actually instantiating
esto no sería válido porque ahora está tratando de crear un objeto concreto a partir de una implementación abstracta.
Animal baby2 = new Dog(); //HERE!!!!!!!!!!!!!!!!!!!!!!
Seguramente no estás instanciando el Animal. Usted solo está refiriendo la instancia Dog a él. En java podemos tomar la referencia de superclase.
En realidad, puedes crear una instancia de la interfaz. Aquí está el código que puedes probar
public static void main(String args[]) {
System.out.println(new Animal() {
public String toString() {
return "test";
}
});
}
Este programa se ejecuta con éxito e imprime la test
Pruébalo.
Interface Animal actúa como el tipo de datos para la clase Dog. En realidad estás instanciando la clase Dog, no la interfaz o su tipo de datos.
Dog
no es una interfaz: Dog
es una clase que implementa la interfaz Animal
.
No hay nada adverso pasando aquí.
Tenga en cuenta que puede instanciar una implementación anónima de una interfaz, así:
Animal animal = new Animal() {
public void Eat(String food_name) {
System.out.printf("Someone ate " + food_name);
}
};
Para tener una imagen más amplia:
Animal [] Zoo = new Animal[10] ; // is also correct
pero por qué ?
La idea es que en la tabla anterior puedes poner 10 animales de diferentes tipos. Las únicas condiciones para esto es que todos los animales que ingresan al Zoo deben implementar la interfaz Animal.
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();}
}
}
Consideremos el siguiente código:
interface Cookable {
public void cook();
}
class Food {
Cookable c = new Cookable() {
public void cook() {
System.out.println("anonymous cookable implementer");
}
};
}
El código anterior crea una instancia de una clase interna anónima , pero aquí, la nueva clase just-in-time es un implementador de la interfaz Cookable . Y tenga en cuenta que esta es la única vez que verá la sintaxis:
new Cookable()
donde Cookable es una interfaz en lugar de un tipo de clase no absorbente. Piénselo: no puede crear instancias de una interfaz , pero así es como se ve el código. Pero, por supuesto, no está creando una instancia de un Cookable object
: está creando una instancia de un nuevo anonymous implementer of Cookable
.
Puedes leer esta línea:
Cookable c = new Cookable(){}
como "Declara una variable de referencia de tipo Cookable que, obviamente, se referirá a un objeto de una clase que implementa la interfaz Cookable . Pero, oh, sí, todavía no tenemos una clase que implemente Cookable , así que vamos a haga uno aquí, en este momento. No necesitamos un nombre para la clase, pero será una clase que implemente Cookable , y este paréntesis comienza la definición de la nueva clase implementadora ".
Importante recordar para implementadores de interfaz anónimos: pueden implementar solo una interfaz. Simplemente no hay ningún mecanismo para decir que su clase interna anónima va a implementar múltiples interfaces. De hecho, una clase interna anónima ni siquiera puede extender una clase e implementar una interfaz al mismo tiempo. La clase innve tiene que elegir ser una subclase de una clase con nombre y no implementar ninguna interfaz en absoluto o implementar una sola interfaz.
Así que no se deje engañar por ningún intento de instanciar una interfaz, excepto en el caso de una clase interna anónima. Lo siguiente no es legal:
Runnable r = new Runnable(); // can''t instantiate interface
mientras que el siguiente es legal, porque está creando una instancia de un implementador de la interfaz Runnable (una clase de implementación anónima):
Runnable r = new Runnable() {
public void run(){ }
};
Aquí solo hace referencia a la interfaz, pero la instanciación solo la realiza la clase. por ejemplo
Animanl a = nuevo Animal de Perro a - la variable se denomina nuevo Perro - ahora se asigna la Memoria