Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What happens when an abstract class implements an interface in Java

I am new to Java, coming from a C++ background and I try to understand the concept of interface and abstract class implementing an interface. What exactly happens when an abstract class implements an interface? Does this work like inheritance, i.e. all interface methods belong also to the abtract class eventhough they are not implemented in it? Or will only the implemented methods belong to the abstract class? So is there any difference between implements and extends, except that one is used to implement interfaces and the other one is used for inheritance?

like image 551
AlexandraC Avatar asked Apr 10 '18 15:04

AlexandraC


2 Answers

You can imagine an abstract class as an unfinished class. It's like a template for actual real classes. Interfaces are mainly used to describe properties, like CanWalk, IsCloseable, HasAName and so on.

There is no big difference between both concepts from the language perspective, other than that you can only extend from one class but are allowed to implement multiple interfaces.

In the end of the inheritance chain you will always have non-abstract concrete classes. Which is obvious, you can't use unfinished classes in the end, you need to finish them. That's why

Animal animal = new Animal();

does not work if Animal is abstract. We need to create instances of finished classes, like a Dog who extends from Animal.


And at that point, where you have a finished (non-abstract) class, all abstract methods need to be implemented. It doesn't matter from where those methods come from, abstract classes or interfaces, they need to be implemented.

So if you have an abstract class and implement an interface with it, you have two options for the interface methods. You either

  • implement them in the abstract class or
  • you leave them abstract, but then some of your more concrete children need to implement it.

Example

Let's suppose we have an interface like

public interface CanMakeNoise {
    void makeNoise();
}

and the abstract class

public abstract class Animal implements CanMakeNoise {
    public abstract void jump();

    ...
}

together with a concrete extending class

public class Dog extends Animal {
    ...
}

Since Dog is not abstract, all methods need to be implemented. That is, we need implementations for jump and makeNoise. For the makeNoise method we have two options, either Animal implements it or it leaves it abstract, then Dog needs to implement it:

// Variant 1
public abstract class Animal implements CanMakeNoise {
    public abstract void jump();

    @Override
    public void makeNoise() {
        System.out.println("hello, what's up");
    }
}

or

// Variant 2
public abstract class Animal implements CanMakeNoise {
    public abstract void jump();
}

public class Dog extends Animal {
    @Override
    public void makeNoise() {
        System.out.println("Wuff wuff");
    }
}

And of course Dog needs to implement jump:

public class Dog extends Animal {
    @Override
    public void jump() {
        System.out.println("Boing");
    }

    ...
}

In this case it's probably better to leave the implementation of makeNoise up to more concrete classes since Animal has no clue how a specific animal will sound like.

Extending the example, if you have even more concrete classes like a Chihuahua extends Dog, you could implement the makeNoise in Dog since all dogs do "Wuff, wuff".

like image 92
Zabuzard Avatar answered Oct 22 '22 01:10

Zabuzard


A method belongs to implementing class of course. I won't say that it doesn't matter where it comes from because of polymorphism. In Java you don't have multi-inheritance but you can implement multiple interfaces, so this is giving you more options about the hierarchy.

like image 30
tomasb Avatar answered Oct 21 '22 23:10

tomasb