44

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?

Macintosh Fan
  • 355
  • 1
  • 4
  • 18
user1535147
  • 1,325
  • 5
  • 14
  • 21
  • 6
    Note: by convention, methods should start with a lower case letter – fge May 25 '13 at 14:59
  • 5
    A) Actually, an interface can be instantiated ... anonymously. B) You're not instantiating an interface, you're instantiating a `Dog` – Brian Roach May 25 '13 at 15:05
  • 1
    @BrianRoach What do you mean in point A? Anonymous class is class (not interface) that extends other class or implements interface. It is the same case as in OP example or as [instantiating an abstract class](http://stackoverflow.com/questions/13670991/interview-can-we-instantiate-abstract-class/13671003#13671003). Or am I missing something? – Pshemo May 25 '13 at 15:10
  • @Pshemo `Runnable r = new Runnable() { public void run() { System.out.println("hi!"); }};` ;) (And yeah ... it's syntactic sugar ... it's really an anonymus class that implements `Runnable`) – Brian Roach May 25 '13 at 15:12
  • 1
    @BrianRoach This will produce instance of anonymous class that will implement Runnable. If you compile your code you will see additional file named `xxx$1.class`. So it wont instantiate interface, but anonymous class that implements that interface. Also try to print `System.out.println(r.getClass());`. – Pshemo May 25 '13 at 15:15

15 Answers15

53

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 :)

Gastón Saillén
  • 12,319
  • 5
  • 67
  • 77
zw324
  • 26,764
  • 16
  • 85
  • 118
  • 3
    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 May 25 '13 at 15:09
  • 2
    @user1535147 Generally this is used in methods like this `public void Foo(Animal bar)`, which will take _any_ class implementing `Animal`. – mwerschy May 25 '13 at 15:28
  • 5
    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, `Animal`s enough). – zw324 May 25 '13 at 15:31
  • In fact you CAN. Runnable is one of the many interfaces that can be instantiated. – frankelot Dec 09 '14 at 20:48
  • 5
    @feresr no, you can't. When you "instantiate" `Runnable`, you actually create a new instance of anonymous class that implements `Runnable` interface. – nikoliazekter Oct 30 '15 at 09:17
  • @nikoliazeketer I know, thats what I meant. Didnt want yo confuse OP further with technical terms – frankelot Oct 31 '15 at 14:24
  • And remember that baby2 is a REFERENCE to Animal. – Marian Paździoch Apr 20 '16 at 09:56
  • Actually you can instantiate it. You have to implement Eat method though – N.Car Mar 22 '19 at 21:17
31

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);
    }
};
Bohemian
  • 412,405
  • 93
  • 575
  • 722
  • If I may ask, what is this used for? – user1535147 May 25 '13 at 15:20
  • 2
    @user1535147 take a look here: [what-does-it-mean-to-program-to-an-interface](http://stackoverflow.com/questions/383947/what-does-it-mean-to-program-to-an-interface) – Pshemo May 25 '13 at 15:23
  • 5
    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". – Bohemian May 25 '13 at 15:25
  • @Pshemo Thanks for the link. That dude with his funny examples is cool. – user1535147 May 25 '13 at 15:32
24

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.

Setu Kumar Basak
  • 11,460
  • 9
  • 53
  • 85
10

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.

Makoto
  • 104,088
  • 27
  • 192
  • 230
2
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.

Undo
  • 25,519
  • 37
  • 106
  • 129
John
  • 145
  • 1
  • 9
2

This is a case of polymorphism, It looks like you are creating 'Animal' object but it is not. You are creating 'Dog' object which is calculated on run time.'Animal' acts as contract. Interface can not be instantiated directly but can be used as type by upcasting its subclass. You can also use anonymous class to instantiate an object as 'Animal' type.

   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
Yogendra Paudyal
  • 1,387
  • 1
  • 12
  • 17
1

The interface Animal is not be intantiated but be implemented by Dog.And a Dog is intantiated

BlackJoker
  • 3,099
  • 2
  • 20
  • 27
1

When you say:

Animal baby2 = new Dog();

the reference type is Animal(the interface) which points to a concrete implementations (Dog). The object type Dog is concrete and can be instantiated. In this case, as long as Dog hasanimal point to Dog. a concrete implementation of all the methods in the interface, you can make a reference type of

If you did something like,

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

this would be invalid because now you are trying to create a concrete object from an abstract implementation.

1

The Interface Animal acts as the data type to the class Dog. You're actually instantiating the Dog class not the interface or it's data type.

1

To have a wider picture :

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

but why ?

The whole idea is that in the table above you can put 10 animals of different types. The only conditions for this is that all the animals entering the Zoo must implement the interface 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();}
}
}
Java Main
  • 1,521
  • 14
  • 18
  • Nice to point out this interesting aspect. Google did the same thing [here](https://developer.android.com/guide/topics/ui/dialogs.html#PassingEvents), which baffled me for a while. – SMBiggs Aug 10 '16 at 15:48
1

You can't instantiate an interface. The functionality can be considered similar to that of an abstract class. You can have a reference to the interface but you don't create an object of interface. If you do something like this....

Animal a = new Animal(); The compiler will show an error- "Cannnot instantiate the type Animal".

Kinshuk
  • 21
  • 7
1

Java 8 let you use, the functional interface,

@FunctionalInterface // this is not mandatory 
interface A{
    void m1(); // only one abstract method allowed for functional interface
}

class Main{
   public static void main(String a[]){

      // old usage
      A a1 = new A(){
        @Override
        public void m1(){
           System.out.println("Call Me normally");
        }
      };

      a1.m1();

      // new in java 8, functional interface
      A a2 = ()-> System.out.println("Call Me as functional interface");
      a2.m1();
 
   }
}
Muhammad
  • 2,572
  • 4
  • 24
  • 46
0

Actually you can instantiate the interface. Here is the code you can try

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

This program runs successfully and prints test Try it.

carloabelli
  • 4,289
  • 3
  • 43
  • 70
Amol Dixit
  • 611
  • 7
  • 13
  • 2
    **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 !!! – user3437460 Sep 05 '15 at 06:40
0

Here it is just referencing to the interface but instantiation is done by the class only. for e.g

Animanl a = new Dog Animal a - variable is referenced new Dog - now Memory is allocated

sanjil
  • 1
0

What have you done is type casting. You have created an instance of class dog and has type caste it to interface animal.It is an example of runtime polymorphosim. But yes an interface can be implemented and I have reached here while searching for this. i.e.

public class demo16{
interface cardio{
    void run();
}

static void foo(){
    cardio c = new cardio(){ //HENCE instance of "interface cardio" is being created inside a method foo
        public void run(){
            System.out.println("How you doing  ! ");
        }; //HENCE observe the ";" beside }
    };     //HENCE observe the ";" beside }
    c.run();
}

public static void main(String [] args){
    foo();
}

}