Search code examples
javainheritanceinterfacejvmabstract

Are there any differences between a normal interface class and an abstract class that only has abstract methods?


I was just curious if they are treated any differently.

For example if we have:

The interface:

public interface Test {
    public void method();
}

And the abstract class:

public abstract class Test {
    public abstract void method();
}

Will the JVM treat these classes any differently? Which of the two takes up more disk space during storage, which one will use up the most runtime memory which one does more operations(performs better).

This question isn't about when to use interfaces or abstract classes.


Solution

  • Yes, they are different.

    With an interface, clients could implement it aswell as extend a class:

    class ClientType implements YourInterface, SomeOtherInterface { //can still extend other types
    
    }
    

    With a class, clients will be able to extend it, but not extend any other type:

    class ClientType extends YourClass { //can no longer extend other types
    
    }
    

    Another difference arises when the interface or abstract class have only a single abstract method declaration, and it has to do with anonymous functions (lambdas).

    As @AlexanderPetrov said, an interface with one method can be used as a functional interface, allowing us to create functions "on-the-fly" where ever a functional interface type is specified:

    //the interface
    interface Runnable {
        void run()
    }
    
    //where it's specified
    void execute(Runnable runnable) {
        runnable.run();
    }
    
    //specifying argument using lambda
    execute(() -> /* code here */);
    

    This cannot be done with an abstract class. So you cannot use them interchangably. The difference comes in the limitations of how a client can use it, which is enforced by the semantics of the JVM.

    As for differences in resource usage, it's not something to worry about unless it's causing your software problems. The idea of using a memory-managed language is to not worry about such things unless you are having problems. Don't preoptimize, I'm sure the difference is negligable. And even if there is a difference, it should only matter if it may cause a problem for your software.

    If your software is having resource problems, profile your application. If it does cause memory issues, you will be able to see it, as well as how much resources each one consumes. Until then, you shouldn't worry about it. You should prefer the feature that makes your code easier to manage, as opposed to which consumes the least amount of resources.