1

Say I have an Animal class, and I want different classes and functionality for each kind of animal. There are two ways of doing this:

  1. Method overriding through inheritance:

    public class Animal {
        public void sound() {}
    }
    
    public class Dog extends Animal {
        public void sound() {
            System.out.println("bark");
        }
    }
    
    public static void main(String[] args) {
        Animal dog = new Dog();
        dog.sound();
    }
    
  2. By extending the Animal abstract class:

    abstract public class Animal {
        abstract public void sound();
    }
    
    public class Dog extends Animal {
        public void sound() {
            System.out.println("bark");
        }
    }
    
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.sound();
    }
    

So why do we use abstract classes at all, when the exact same thing is being done by the first method? I understand why we use interfaces - it establishes a contract that any class implementing it has to have certain methods and attributes. But what is the use of an abstract class, when the same thing can be achieved through simple inheritance?

shmosel
  • 49,289
  • 6
  • 73
  • 138
lebowski
  • 1,031
  • 2
  • 20
  • 37
  • 1
    The same thing? So if you don't create a `sound()` in `Dog`, then what will happen in both version? Obviously not the same. And that tells you why `abstract` is better for most cases. – Tom Jul 28 '17 at 23:43
  • With `abstract` class you have 2 type of function: with and without `abstract` keyword. With `abstract` keyword you force all child class has to implement this method. Without `abstract` keyword you can self implement this method at parent, on each child you can override if need or can using the parent's implementation. If using `Interface` then you can not implement a method, each child has to self implement it. – TuyenNTA Jul 28 '17 at 23:44
  • In the first case you have to implement the method in `Animal`, but in the second case you don't. Also, the abstract class is not created in memory, see here: https://stackoverflow.com/questions/20756679/how-jvm-handles-abstract-class-in-java – tima Jul 28 '17 at 23:44
  • 2
    If `Animal` is an incomplete class then you don't want clients to be able to create instances of it. You signal this by making it abstract. In case 1 a client could do `Animal a = new Animal();`. In case 2 this would be caught by the compiler. – RaffleBuffle Jul 28 '17 at 23:50
  • abstract function HAVE to be implemented. parent methods do not. thats the difference. moreover, abstract classes cannot be instantiated. you could make a class with private constructor, but why do that when you have abstract classes – user2914191 Jul 29 '17 at 00:03

2 Answers2

5

An important thing about an abstract class - it cannot be instantiated. Therefore, depending on the nature of your problem, sometimes you would want to use it.

An animal is actually a good example:

Since there are no instances of animals in the world, but instances of specific animals only. So - you would want to have an abstract class Animal and specific animals classes will extend it, and implement its abstract methods.

Also, you can have in an abstract class non-abstract methods - you would use these ones when there's a shared/common behavior for every class that extends it.

SHG
  • 2,516
  • 1
  • 14
  • 20
  • I see what you mean. Can you give a similar example where it would be better to use overriding and inheritance, instead of using abstract class? – lebowski Jul 28 '17 at 23:51
  • 1
    @lebowski I think you misunderstand -- when you have an abstract class you can both inherit from it and override it. A major difference between an abstract class and an interface is that the abstract class can provide _default_ implementations of methods, which you can then override. – Stephen P Jul 28 '17 at 23:58
  • 1
    Sure. An example for that would be a context where the base class and the extending class can be both instantiated - let's say a `Rectangle` and `Square`. Both of them exist in the world, but `square` is just a specific `rectangle`, has more characteristics. – SHG Jul 28 '17 at 23:58
  • 1
    @SHG Those are some really good examples, and this definitely cleared away some of my confusion. Marking your answer as accepted. – lebowski Jul 29 '17 at 00:01
2

There are fundamental concepts broken by not making Animal abstract or interface. I recommend you reading here.

Just as an example of why your posted hierarchy is wrong on your scenario. Anyone could do this:

Animal noanimal = new Animal();
noanimal.sound();

Which has no sense at all; animal is something abstract in your scenario, not concrete. You shouldn't be able to instantiate "Animal" but instead one of its concrete implementations.

Also, by the look of your scenario, Animal should be an interface. It's not providing any common implementation to be shared by its children (and even if it was, i would keep Animal as interface and just have a BaseAnimal abstract class; or just use composition but that's out of the scope of this question).

albert_nil
  • 1,648
  • 7
  • 9