Abstract classes and interfaces
Abstract classes
An abstract class is an unfinished blueprint. It can't be instantiated, and it can declare abstract methods with no body, which every subclass must implement:
abstract class Shape {
abstract double area(); // no body: each shape must supply one
void describe() { // an ordinary method, shared by all shapes
System.out.printf("%s with area %.2f%n", getClass().getSimpleName(), area());
}
}
class Circle extends Shape {
double r;
Circle(double r) { this.r = r; }
@Override double area() { return Math.PI * r * r; }
}
class Triangle extends Shape {
double base, height;
Triangle(double base, double height) { this.base = base; this.height = height; }
@Override double area() { return 0.5 * base * height; }
}
public class Main {
public static void main(String[] args) {
Shape[] shapes = { new Circle(2), new Triangle(6, 4) };
for (Shape s : shapes) s.describe();
// new Shape(); // error: Shape is abstract
}
}This fixes a weakness in the last lesson's Shape, whose area() returned a meaningless 0. Now a subclass that forgets to write area() doesn't compile.
Interfaces
An interface is a pure contract: a list of methods that a class promises to provide.
interface Payable {
double amountDue();
}
interface Printable {
void print();
}
class Invoice implements Payable, Printable {
String client;
double amount;
Invoice(String client, double amount) {
this.client = client;
this.amount = amount;
}
public double amountDue() { return amount; }
public void print() { System.out.println("Invoice for " + client + ": " + amount); }
}
class Salary implements Payable {
String employee;
double monthly;
Salary(String employee, double monthly) {
this.employee = employee;
this.monthly = monthly;
}
public double amountDue() { return monthly; }
}
public class Main {
public static void main(String[] args) {
Payable[] bills = { new Invoice("Acme", 1500), new Salary("Asha", 4200) };
double total = 0;
for (Payable p : bills) total += p.amountDue();
System.out.println("Total due: " + total);
new Invoice("Globex", 900).print();
}
}- A class
implementsan interface and must provide all its methods, aspublicmethods. - A class can implement many interfaces, but extend only one class.
- Unrelated classes, like an invoice and a salary, can share an interface, so other code can treat them alike.
Default methods
interface Greeter {
String name();
default String greet() {
return "Hello, " + name() + "!";
}
}
class Friendly implements Greeter {
public String name() { return "Asha"; }
}
class Formal implements Greeter {
public String name() { return "Dr. Rao"; }
@Override
public String greet() { return "Good evening, " + name() + "."; }
}
public class Main {
public static void main(String[] args) {
System.out.println(new Friendly().greet());
System.out.println(new Formal().greet());
}
}A default method has a body that implementing classes inherit, and may override. It lets an interface gain new methods without breaking every class that already implements it.
Comparable: sorting your own objects
The Java library is built on interfaces. Implement Comparable, and Arrays.sort knows how to order your objects:
import java.util.Arrays;
class Student implements Comparable<Student> {
String name;
int score;
Student(String name, int score) {
this.name = name;
this.score = score;
}
@Override
public int compareTo(Student other) {
return Integer.compare(other.score, score); // higher scores first
}
@Override
public String toString() { return name + " " + score; }
}
public class Main {
public static void main(String[] args) {
Student[] students = { new Student("Leo", 78), new Student("Asha", 92), new Student("Mei", 85) };
Arrays.sort(students);
System.out.println(Arrays.toString(students));
}
}compareTo returns a negative number if this object comes first, a positive one if the other does, and zero if they're equal.
Abstract class or interface?
| Abstract class | Interface | |
|---|---|---|
| fields | any kind | constants only |
| constructors | yes | no |
| a class can use | only one | any number |
| best for | sharing code and state among closely related classes | a capability that unrelated classes can share |
When in doubt, start with an interface.