1

So, I want to create a correlation between two classes, from what I have read in some design patterns, it convenient, to use an interface, (in Android Studio it is used to bind a fragment with a activity).

Look at this code:

First, we have class A:

public class A {

public static void main(String[] args) {
    B b = new B();
    b.foo();
}
}

Then, we have class B:

class B {
private int i;

interface Drawable {
    void show(int i);
}

public B() {
    this.i = 5393;
    drawable = new C();
}
private Drawable drawable;

public void foo() {
    drawable.show(this.i);
}
}

And at the end class C:

class C implements B.Drawable {

@Override
public void show(int i) {
    System.out.println("I'm showing this method, and i = " + i);
}
}

What I'm wrapping my head around is this line:

drawable = new C();

Can someone explain me how are we assigning new object from class C, to a interface, I know it is because class C implements that interface, yet, it is hard for me to get it all. The general view of this operation is pretty harsh for me to overcome.

In Android we are assigning that interface to a Activity, (the recent patch changed it into a context, which is a instance of a Activity).

Phantômaxx
  • 37,901
  • 21
  • 84
  • 115
  • 1
    Possible duplicate of [What does it mean to "program to an interface"?](https://stackoverflow.com/questions/383947/what-does-it-mean-to-program-to-an-interface) – Yassin Hajaj May 12 '18 at 12:35

1 Answers1

0

This is polymorphism at work.

In Java, you can assign an instance of a subclass (or implementation of interface) to a variable of type superclass (or interface).

Now, an interface cannot actually be instantiated. You can't call new on an interface and get an instance of the interface. However, you can make a variable of the type of the interface (in this case, the B.Drawable), and assign it an instance of any implementing class (in this case, C).

One simple way to get some intuition about this is:

Consider an interface of type Car, for use in a video game. Say it only contains some methods, representing the behavior of a car (specifically, what we can get the car to do). Say it has startEngine(), changeGear(), driveAhead(), and other such methods. The exact implementation of these could be different (gear could be changed manually or automatically, ignition systems could change, etc.) All cars would have these common methods, however, and you could make a variable of type Car, and then use it in the video game. You would have a single set of methods to call for any type of car, simplifying your coding.

But the interface cannot be instantiated. So you implement it, in various classes, and instantiate these classes. You could have a Mercedes, a Ferrari, some other cars, with their own properties, and their own implementation of methods. Rather than create a separate reference variable for each type of car, you simply assign the instance of any car (obtained by the statement phrase new Mercedes(), new Ferrari(), etc.), to the Car variable. Then just use the methods declared in Car.

Vineet
  • 346
  • 6
  • 18
  • Thank You for your answer, really good visualization. One thing that I'm not sure, is that, You can "kind of" instantiate an interface calling "new" on it, You just have to implement a anonymous version of it. And yes, I know, that it would not be a interface directly, but a "child" implementation of it. Like so: someInterface s = new someInterface() { @Override public void show() { System.out.println("Hello there"); } }; s.show(); – Łukasz Tulczyjew May 12 '18 at 13:36
  • Yes, and this is still creating an implemented interface, but one that is anonymous and not available anywhere else. I'm not sure how the implementation in bytecode and memory works, but logically, it is similar to implementing the interface in another class, like in your question – Vineet Jul 24 '20 at 10:59