Interfaces and Abstract Classes
Defining contracts and partial implementations
Introduction
In this lesson, you'll learn about interfaces and abstract classes in Java. Coming from JavaScript, you already have a foundation for understanding this concept. We'll build on that knowledge while highlighting the key differences.
In JavaScript, you're familiar with defining contracts and partial implementations.
Java has its own approach to defining contracts and partial implementations, which we'll explore step by step.
The Java Way
Let's see how Java handles this concept. Here's a typical example:
// Interface: pure contract (all methods abstract by default)
public interface Shape {
double area();
double perimeter();
// Default method (Java 8+)
default String describe() {
return String.format("Area=%.2f, P=%.2f", area(), perimeter());
}
}
// Abstract class: partial implementation
public abstract class AbstractShape implements Shape {
protected String color;
AbstractShape(String color) { this.color = color; }
// area() still abstract — subclasses must implement
public abstract double area();
}
// Concrete class
public class Circle extends AbstractShape {
private double radius;
Circle(double r, String color) { super(color); this.radius = r; }
public double area() { return Math.PI * radius * radius; }
public double perimeter() { return 2 * Math.PI * radius; }
}
// Multiple interfaces allowed
public class Ring implements Shape, Serializable { ... }
void printShape(Shape s) {
System.out.println("Area: " + s.area());
}Comparing to JavaScript
Here's how you might have written similar code in JavaScript:
// JS has no interfaces — duck typing rules
// Any object with the right methods works
class Circle {
constructor(r) { this.radius = r; }
area() { return Math.PI * this.radius ** 2; }
perimeter() { return 2 * Math.PI * this.radius; }
}
class Rectangle {
constructor(w, h) { this.w = w; this.h = h; }
area() { return this.w * this.h; }
perimeter() { return 2 * (this.w + this.h); }
}
function printShape(shape) {
console.log(`Area: ${shape.area()}`);
}
printShape(new Circle(5));
printShape(new Rectangle(3, 4));You may be used to different syntax or behavior.
interface defines a pure contract; abstract class provides partial implementation
You may be used to different syntax or behavior.
A class can implement multiple interfaces but extend only one class
You may be used to different syntax or behavior.
interface methods are public abstract by default; fields are public static final
You may be used to different syntax or behavior.
Default methods (Java 8+) let interfaces have concrete method implementations
You may be used to different syntax or behavior.
Abstract classes can have constructors, fields, and non-abstract methods
Step-by-Step Breakdown
1. Declare an Interface
An interface lists method signatures. Any class that implements it must provide all methods.
// No equivalent — JS relies on duck typinginterface Printable {
void print();
String format();
}2. Implement an Interface
Use 'implements'. A class can implement multiple interfaces separated by commas.
class Report { print() { ... } }class Report implements Printable, Serializable {
public void print() { System.out.println(format()); }
public String format() { return "Report"; }
}3. Abstract Class
Abstract classes provide shared state and partial logic. Subclasses must implement abstract methods.
class Base { method() { throw new Error("not implemented"); } }abstract class Animal {
String name;
Animal(String name) { this.name = name; }
abstract void speak(); // subclass must implement
void describe() { System.out.println(name + " says:"); speak(); }
}4. Interface vs Abstract Class
Choose interface when you only need a contract. Choose abstract class when you need shared state or a partial implementation.
// In JS both patterns use regular classes// Use interface when: multiple inheritance needed, pure contract
// Use abstract class when: shared fields/logic, single inheritance ok
interface Flyable { void fly(); }
abstract class Vehicle { int speed; void accelerate() { speed += 10; } }Common Mistakes
When coming from JavaScript, developers often make these mistakes:
- interface defines a pure contract; abstract class provides partial implementation
- A class can implement multiple interfaces but extend only one class
- interface methods are public abstract by default; fields are public static final
Key Takeaways
- interface = pure contract (method signatures + constants); class implements multiple interfaces
- abstract class = partial implementation; class extends only one abstract class
- Default methods in interfaces (Java 8+) allow adding methods without breaking implementations
- Always code to the interface type: Shape s = new Circle() — not Circle s = new Circle()