Создание интерфейсов в Java - программирование
Подтвердить что ты не робот

Создание интерфейсов в Java

У меня есть этот интерфейс:

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

И этот код здесь реализует интерфейс:

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");
    }
}

Мой вопрос: зачем работает код? Интерфейс не может быть создан. Однако в этом случае интерфейс был создан (помечен комментарием "ЗДЕСЬ!!!!!!!!!!!!!" ).

Что здесь происходит?

4b9b3361

Ответ 1

Нет, это не так - вы создаете экземпляр Dog, но, поскольку Dog - это Animal, вы можете объявить переменную как Animal. Если вы попытаетесь создать экземпляр интерфейса Animal это будет:

Animal baby2 = new Animal();

Попробуйте, и смотрите, как компилятор кричит в ужасе :)

Ответ 2

Dog не является интерфейсом: Dog - это класс, реализующий интерфейс Animal.

Здесь нет ничего неприятного.


Обратите внимание, что вы можете создать анонимную реализацию интерфейса, например:

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

Ответ 3

Давайте рассмотрим ниже код:

interface Cookable {
    public void cook();
}

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

Предыдущий код создает экземпляр анонимного внутреннего класса, но здесь новый класс "точно в срок" является реализацией интерфейса Cookable. И обратите внимание, что это единственный раз, когда вы увидите синтаксис:

new Cookable()

где Cookable - это интерфейс, а не неабстрактный тип класса. Подумайте об этом: вы не можете создать экземпляр интерфейса, но это похоже на то, что делает код. Но, конечно, это не создание экземпляра Cookable object - это создание экземпляра нового anonymous implementer of Cookable.

Вы можете прочитать эту строку:

   Cookable c = new Cookable(){}

as "Объявите ссылочную переменную типа Cookable, которая, очевидно, будет ссылаться на объект из класса, реализующего интерфейс Cookable. Но, о, да, у нас еще нет класса, реализующего Cookable, поэтому мы собираемся сделайте один прямо здесь, прямо сейчас. Нам не нужно имя для класса, но это будет класс, который реализует Cookable, и эта фигурная скобка начинает определение нового реализующего класса. "

Важно помнить, что для анонимного интерфейса implementers-- они могут реализовывать только один интерфейс. Просто нет никакого механизма, чтобы сказать, что ваш анонимный внутренний класс будет реализовывать несколько интерфейсов. Фактически, анонимный внутренний класс не может даже расширять класс и одновременно реализовывать интерфейс. Класс innve должен выбрать либо быть подклассом именованного класса, а не напрямую реализовывать какой-либо интерфейс, либо реализовывать отдельный интерфейс.

Так что не дайте себя обмануть любыми попытками создания экземпляра интерфейса, за исключением случая с анонимным внутренним классом. Следующее не является законным:

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

тогда как следующее допустимо, потому что оно создает экземпляр реализации интерфейса Runnable (анонимный класс реализации):

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

Вы можете прочитать мою статью здесь.

Ответ 4

То, что вы наблюдаете здесь, это аспект отклонения зависимостей SOLID.

Ваш код зависит от абстракции контракта Animal, создавая его конкретную реализацию. Вы просто заявляете: "Я создаю какой-то объект, но независимо от того, что этот объект на самом деле, он будет связан с контрактом интерфейса Animal".

Возьмем, например, такие виды объявлений:

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

В обоих случаях основным аспектом списка и карты является то, что они следуют за общим контрактом для List и Map.

Ответ 5

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

Несомненно, вы не создаете животное. Вы ссылаетесь только на экземпляр Dog. В java мы можем взять ссылку суперкласса.

Ответ 6

Интерфейс Animal не будет запутанным, но будет реализован Dog. И a Dog запутан.

Ответ 7

Когда вы говорите:

Animal baby2 = new Dog();

ссылочным типом является Animal (интерфейс), который указывает на конкретные реализации (Dog). Тип объекта Dog является конкретным и может быть создан. В этом случае, пока собака hasanimal указывает на Собака. конкретная реализация всех методов в интерфейсе, вы можете сделать ссылочный тип

Если вы сделали что-то вроде

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

это неверно, потому что теперь вы пытаетесь создать конкретный объект из абстрактной реализации.

Ответ 8

Интерфейс Animal действует как тип данных для класса Dog. Вы фактически создаете экземпляр класса Dog, а не интерфейс или тип данных.

Ответ 9

Это полиморфизм. Похоже, вы создаете объект "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

Ответ 10

Чтобы получить более широкое изображение:

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

но почему?

Вся идея состоит в том, что в приведенной выше таблице вы можете поместить 10 животных разных типов. Единственные условия для этого - то, что все животные, входящие в Зоопарк, должны реализовать интерфейс 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();}
}
}

Ответ 11

Фактически вы можете создать экземпляр интерфейса. Вот код, который вы можете попробовать

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

Эта программа работает успешно и печатает test Попробуйте.

Ответ 12

Здесь он просто ссылается на интерфейс, но инстанцирование выполняется только классом. например,

Animanl a = новая собака Ссылка на a-переменную Animal новая собака - теперь выделена память