Search code examples
javaoopinterfaceabstract-classabstraction

Can abstraction be achieved using concrete classes?


I have tried my best finding answer to this question but in vain.
So, I was asked this question in an interview and I answered YES. Since abstraction is nothing but simply hiding the implementation details from user, such that the user need not worry about the implementation and only knows about the method signature(Type of object that need to be passed and the return type). Based on the type of object passed the developer can decide the implementation and return the corresponding result. So, according to me this can also be done using concrete normal classes as below.

public class LearnAbstraction {

    public static void main(String[] args) {
        Animal animal = new Tiger();
        SpeakingAnimal sa = new SpeakingAnimal();
        sa.getAnimalToSpeak(animal);
    }
}

class SpeakingAnimal {
    public void getAnimalToSpeak(Animal animal){
        animal.speak();
    }
}

class Animal{
    public void speak(){
        System.out.println("I am an Animal");
    }
}

class Tiger extends Animal {
    public void speak() {
        System.out.println("I am an Animal and Tiger");
    }
}

class Horse extends Animal {
    public void speak() {
        System.out.println("I am an Animal and Horse");
    }
}

I know it is not a correct way to achieve abstraction and it must be done using Interfaces or abstract classes. But, the question is whether abstraction can be achieved using concrete classes or not(Let's leave the appropriate way aside). So, is it correct to say YES as the answer to this question?


Solution

  • An abstract class cannot produce instances; you can ensure it doesn't by declaring a private constructor.

    Here is an example:

    class Animal{
        private Animal() {
        }
    
        public void speak(){
            System.out.println("I am an Animal");
        }
    
        static class Tiger extends Animal {
            public void speak() {
                System.out.println("I am an Animal and Tiger");
            }
        }
    
        static class Horse extends Animal {
            public void speak() {
                System.out.println("I am an Animal and Horse");
            }
        }
    }