0

I'm just getting started with interfaces and I cannot grasp the concept.

class Client {
    IServer x = new Server();
    void m() {
        x.p();
    }
}

interface IServer {
    void n();
    void p();
}

class Server implements IServer{
    public void n() {
        System.out.println("Methode n");
    }
    public void p() {
        System.out.println("Methode p");
    }
}

So client should be able to use the methods provided by server through the interface IServer. Is IServer x = new server(); correct? The examples that I found (https://www.w3schools.com/java/java_interface.asp) all build interfaces and then the main class calls the other class without using the interface. Thank you for your help, I guess I'm just missing something obvious here...

Esoterik
  • 15
  • 5
  • 1
    Yes `IServer x = new server();` is correct. It it weren't, there'd be no point in having in having interfaces at all because they would be useless. – Kevin Anderson Oct 31 '19 at 12:00
  • 4
    _Unrelated:_ According to standard Java naming conventions, class names start with an uppercase letter (i.e. `client` → `Client`, `server` → `Server`). Following naming conventions helps others, and possibly you, read your code (also helps Stack Overflow's syntax highlighting). – Slaw Oct 31 '19 at 12:02
  • There's nothing wrong with this example, but the real power of interfaces isn't being demonstrated because you're manually instantiating one of the implementations with `new Server()` inside the class that uses it. Once you start doing Dependency Injection, the purpose of interfaces should become clearer – byxor Oct 31 '19 at 12:23

2 Answers2

0

A better documentation is the official at https://docs.oracle.com/javase/tutorial/java/IandI/createinterface.html

There are a number of situations in software engineering when it is important for disparate groups of programmers to agree to a "contract" that spells out how their software interacts. Each group should be able to write their code without any knowledge of how the other group's code is written. Generally speaking, interfaces are such contracts.

With an Interface, you can enforce a Class to have a particular behavior, defined inside the Interface, BUT implemented inside the class that implement that Interface.

And also, if you know that an object Dog implements the Interface Run and that Interface declare the method run() {}, you can safely invoke the method run on the object Dog, because it contains the method implementation:

Interface Run
{
    public void run();
}

class Dog implements Run
{
    public void run()
    {
        // the dog is running
    }
}

Dog dog = new Dog();
dog.run();
user2342558
  • 5,567
  • 5
  • 33
  • 54
0

A good explanation of how interfaces work and why they're used can be done with the following example. Let's say we have a zoo object with animals. We want all the animals to be able to make a noise depending on what animal they are. We start with the following class:

public class Zoo {
    private List<Animal> animals;

    public Zoo() {
        animals = new ArrayList<>();
    }

    public void addAnimal(Animal animal) {
        animals.add(animal);
    }

    public void roar() {
        for(Animal a : animals) {
            a.makeNoise();
        }
    }
}

This is basically just an object containing a list of animals and we can add animals to this list. When we call the method roar we want all the animals to make their own noise and print it to the console. Now this is where interfaces are useful, since we know we will have multiple types of animals we can specify what a basic "animal" can do, these are generic traits that describe that they can do something but not how. For instance, a box and a human can both move, but a human can move on its own and a box cannot. Or maybe a human can move up stairs but a dog cannot. Knowing this, we create a basic interface describing that an animal can make a noise:

public interface Animal {
    void makeNoise();
}

This will allow us to create as many animals as we want, while forcing them to implement our defined functionalities. So now, we can create some animals:

public class Cat implements Animal {
    private String name;

    public Cat(String name) {
        this.name = name;
    }

    @Override
    public void makeNoise() {
        System.out.println(name + "said Meow");
    }
}

public class Dog implements Animal {
    @Override
    public void makeNoise() {
        System.out.println("Woof");
    }
}

As you can see, we can give both classes their own functionality, while still enforcing both classes to at least be able to make their respective noise. In this case a cat can have a name, while a dog cannot. This means that we can now fill our Zoo with any animal we want, and since they all have the same overlaying interface we don't have to, for instance, create more than one Collection to store each type of animal. We can just throw them all on one big pile based on their interface and we can call the proper method through the interface:

public void run() {
    Zoo zoo = new Zoo();
    zoo.addAnimal(new Cat("Bob"));
    zoo.addAnimal(new Dog());
    zoo.addAnimal(new Cat("William"));
    zoo.roar();
}

As far as types are concerned. It works like it does in real life. Following our example, a dog is an Animal, but an animal is not necessarily a dog. Since our code in this case (when it's inside the zoo) only knows that it has Animals, but not what specific types, it only allows us access to the functionalities defined in the interface.

This means that, we are allowed to do stuff like:

Animal a = new Dog();
Dog b = new Dog();
Animal c = new Cat("Bob");
Cat d = new Cat("Wilbert");

But not:

Animal a = new Dog();
Dog b = a;

Since, as soon as we assign a and say "you're of type animal" it doesn't know if the data inside a is actually a dog or not.

martijn p
  • 598
  • 4
  • 19