Instantiating interfaces in Java

70,518

Solution 1

No it is not - you are instantiating a Dog, but since a Dog is an Animal, you can declare the variable to be an Animal. If you try to instantiate the interface Animal it would be:

Animal baby2 = new Animal();

Try that, and watch the compiler scream in horror :)

Solution 2

Dog is not an interface: Dog is a class that implements the Animal interface.

There's nothing untoward going on here.


Note that you can instantiate an anonymous implementation of an interface, like so:

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

Solution 3

Let's consider below code:

interface Cookable {
    public void cook();
}

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

The preceding code creates an instance of an anonymous inner class, but here, the new just-in-time class is an implementer of the Cookable interface. And note that this is the only time you will ever see the syntax:

new Cookable()

where Cookable is an interface rather than a nonabstract class type. Think about it: You can't instantiate an interface, yet that's what the code looks like it's doing. But, of course, it's not instantiating a Cookable object-- it's creating an instance of a new anonymous implementer of Cookable.

You can read this line:

   Cookable c = new Cookable(){}

as "Declare a reference variable of type Cookable that, obviously, will refer to an object from a class that implements the Cookable interface. But, oh yes, we don't yet have a class that implements Cookable, so we're going to make one right here, right now. We don't need a name for the class, but it will be a class that implements Cookable, and this curly brace starts the definition of the new implementing class."

Important to remember for anonymous interface implementers-- they can implement only one interface. There simply isn't any mechanism to say that your anonymous inner class is going to implement multiple interfaces. In fact, an anonymous inner class can't even extend a class and implement an interface at the same time. The innve class has to choose either to be a subclass of a named class and not directly implement any interface at all or to implement a single interface.

So don't be fooled by any attempts to instantiate an interface except in the case of an anonymous inner class. The following is not legal:

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

whereas the following is legal, because it's instantiating an implementer of the Runnable interface(an anonymous implementation class):

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

You can read my article here.

Solution 4

What you're observing here is the Dependency inversion aspect of SOLID.

Your code is depending on the abstraction of the Animal contract by instantiating a concrete implementation of it. You're merely stating, "I'm instantating some object, but regardless of what that object actually is, it will be bound to the contract of the Animal interface."

Take, for instance, these sorts of declarations:

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

In both of those cases, the primary aspect of the list and map is that they follow the generic contract for a List and Map.

Solution 5

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

Surely you are not instantiating the Animal. You are only referring the Dog instance to it. In java we can take the super class reference.

Share:
70,518
user1535147
Author by

user1535147

Updated on July 09, 2022

Comments

  • user1535147
    user1535147 almost 2 years

    I have this interface:

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

    And this code here implements the interface:

    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(); // <- this line
            baby2.Eat("Meat");
        }
    }
    

    My question is, why does the code work? An interface cannot be instantiated. Yet in this case, interface was instantiated (marked with the comment).

    What is happening here?

  • user1535147
    user1535147 almost 11 years
    So why instantiate as a interface and then intialize it using a class? As in why don't they do it like this: Dog baby = new Dog();
  • user1535147
    user1535147 almost 11 years
    If I may ask, what is this used for?
  • Pshemo
    Pshemo almost 11 years
    @user1535147 take a look here: what-does-it-mean-to-program-to-an-interface
  • Bohemian
    Bohemian almost 11 years
    It's used when you don't want to create a stand-alone class - you just need to pass some code around. It's java's way of doing a "closure".
  • mwerschy
    mwerschy almost 11 years
    @user1535147 Generally this is used in methods like this public void Foo(Animal bar), which will take any class implementing Animal.
  • zw324
    zw324 almost 11 years
    It's depends - if you need the special functionality in Dog that is not part of the Animal contract (imagine a bark method), then you will need to declare it as a Dog (or use a cast, but that is not necessarily good); but in other cases when you are just using the eat method or just expecting an instance of a subclass of an Animal declaring it as a Animal would be enough, and does not try you to Dog (you can change to Elephant later; also, it documents your intention (hey, Animals enough).
  • user1535147
    user1535147 almost 11 years
    @Pshemo Thanks for the link. That dude with his funny examples is cool.
  • frankelot
    frankelot over 9 years
    In fact you CAN. Runnable is one of the many interfaces that can be instantiated.
  • user3437460
    user3437460 over 8 years
    Who gave this solution a +1 ? You cannot instantiate an interface. When you create an anonymous class, it is the new "nameless" class which implements the interface gets instantiated !!!
  • nikoliazekter
    nikoliazekter over 8 years
    @feresr no, you can't. When you "instantiate" Runnable, you actually create a new instance of anonymous class that implements Runnable interface.
  • frankelot
    frankelot over 8 years
    @nikoliazeketer I know, thats what I meant. Didnt want yo confuse OP further with technical terms
  • Marian Paździoch
    Marian Paździoch about 8 years
    And remember that baby2 is a REFERENCE to Animal.
  • SMBiggs
    SMBiggs almost 8 years
    Nice to point out this interesting aspect. Google did the same thing here, which baffled me for a while.
  • Kai Wang
    Kai Wang about 7 years
    nice "anonymous implementer of Cookable".
  • N.Car
    N.Car about 5 years
    Actually you can instantiate it. You have to implement Eat method though