interfaces - when use abstract class and interface in java




Instanciando interfaces en Java (8)

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í?


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

La interfaz Animal no se integrará sino que será implementada por Dog . Y se integrará un Dog


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.


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.


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(){ }
};






abstract