This can be a bit confusing, so let me explain why abstract methods in interfaces (and sometimes in abstract classes) don’t always have the abstract
keyword in modern Java.
🔎 Historical Context — Before Java 8
Before Java 8, if you defined a method inside an interface, it was implicitly abstract and public.
Example:
public interface MyInterface {
void doWork(); // This is implicitly public and abstract
}
This works the same as:
public interface MyInterface {
public abstract void doWork();
}
✅ Both are 100% equivalent. Adding public abstract
is redundant and optional.
⚡ Why Java Allows It?
1. Convenience and Less Boilerplate
- Interfaces were always meant to contain abstract methods (until Java 8 introduced default/static methods).
- Since all interface methods were inherently abstract and public, Java designers decided you don’t need to explicitly write
abstract
every time. Less clutter.
2. Consistency with Modern Java
- In modern Java, it’s common to write interfaces using:
interface Calculator {
int add(int a, int b);
}
Adding abstract
and public
would add zero value — the compiler knows these are abstract and public anyway.It’s part of Java’s design philosophy — reduce unnecessary repetition.
💡 What About Abstract Classes?
In abstract classes, methods can be either:
- Concrete (with a body).
- Abstract (without a body).
In abstract classes, you can write:
abstract void doSomething();
But you can also add public
if you want:
public abstract void doSomething();
This is more about style and visibility control. In interfaces, public
is implied — in abstract classes, it’s not.
⚠️ Important Rule
Type | Abstract Method Rule |
---|---|
Interface | Methods are public abstract by default (if no body). |
Abstract Class | Methods are not abstract unless explicitly marked abstract . |
✅ Example Recap
Interface
interface Animal {
void makeSound(); // implicitly public abstract
}
Same as
interface Animal {
public abstract void makeSound();
}
Abstract class
abstract class Animal {
abstract void makeSound(); // abstract but package-private
}
This is not public by default! If you want public, you must say it:
abstract class Animal {
public abstract void makeSound();
}
🔥 Quick Rule of Thumb
Type | Public by default? | Abstract by default? |
---|---|---|
Interface Method | ✔️ Yes | ✔️ Yes |
Abstract Class Method | ❌ No (default is package-private) | ❌ No (only if explicitly abstract ) |
⚙️ Why Functional Interfaces Work Without abstract
When you write:
@FunctionalInterface
interface Printer {
void print(String message);
}
This works perfectly because:
void print(String message)
is automatically public abstract.- This is why lambdas can implement functional interfaces directly — they know they’re implementing exactly one abstract method.
Summary — Less Noise, Same Power
✅ Java designers removed the need for abstract
(and public
in interfaces) to make code cleaner.
✅ You can add them if you want, but it’s redundant and just personal style.
✅ This is one of Java’s syntactic conveniences, not a technical limitation.