Abstraction in OOP is most often expressed through abstract classes and interfaces, two related but distinct constructs. An abstract class is one that cannot be instantiated and may contain both abstract methods without implementation and concrete methods with full behavior. A typical Java example declares an abstract Shape class with an abstract area method that subclasses must implement, alongside a concrete describe method that provides shared behavior. Abstract classes are best used when subclasses share common code but must also implement specific behaviors.
An interface, by contrast, defines a contract of methods that implementing classes must provide, traditionally without any state. In Java, a class can implement multiple interfaces but extend only one abstract class. Methods in interfaces are implicitly public and abstract, although modern interfaces since Java 8 may also include default and static methods with concrete implementations. A Drawable interface, for example, declares a draw method that any implementing class, whether Circle or Rectangle, must provide on its own, specifying what a class does without revealing how.
The choice between an interface and an abstract class depends on what the design requires. Interfaces are well suited for defining pure contracts and capabilities without shared state, especially when classes need to combine several different roles. Abstract classes shine when there is shared state, common concrete behavior, constructors, or carefully chosen access modifiers to pass down to subclasses. The two are complementary tools in the OOP toolkit, each suited to a particular kind of abstraction.