Inheritance, interfaces, and exceptions
Java supports object-oriented design through inheritance and interfaces, and handles errors with a structured exception system.
Inheritance with extends
class SavingsAccount extends BankAccount gives SavingsAccount all accessible fields and methods of BankAccount, which it can extend. Java allows only single inheritance of classes: each class has exactly one direct superclass. Every class ultimately inherits from Object, which provides methods such as toString and equals.
Overriding and super
A subclass can override an inherited method by defining it with the same signature, marked @Override so the compiler checks it really overrides something. super.method() calls the parent's version, and super(args) in a constructor calls the parent constructor, which must be the first statement.
Polymorphism
A variable of a superclass type can refer to a subclass object: BankAccount acct = new SavingsAccount();. Calling acct.monthlyUpdate() runs SavingsAccount's version, chosen at run time. This lets code work with general types while each object behaves according to its actual class.
Abstract classes
An abstract class cannot be instantiated and may declare abstract methods without bodies, which subclasses must implement: abstract class Shape { abstract double area(); }. Abstract classes can also contain fields and complete methods, sharing common code among related subclasses.
Interfaces
An interface declares methods that implementing classes promise to provide: interface Drawable { void draw(); }. A class can implement many interfaces, class Circle extends Shape implements Drawable, Comparable<Circle>, which gives flexibility beyond single inheritance. Interfaces can include default methods with bodies since Java 8.
Exceptions
Errors are represented by exception objects. try { ... } catch (IOException e) { ... } finally { ... } handles them; finally always runs. try-with-resources, try (var in = new FileReader(f)) { ... }, closes resources automatically. throw raises an exception, such as throw new IllegalArgumentException("negative").
Checked and unchecked exceptions
Checked exceptions, such as IOException, must be caught or declared with throws in the method signature; the compiler enforces this. Unchecked exceptions, subclasses of RuntimeException such as NullPointerException and ArrayIndexOutOfBoundsException, usually signal programming bugs and need not be declared.
Worked example
abstract class Shape { abstract double area(); } class Rect extends Shape { double w, h; Rect(double w, double h) { this.w = w; this.h = h; } @Override double area() { return w * h; } } class Circle extends Shape { double r; Circle(double r) { this.r = r; } @Override double area() { return Math.PI * r * r; } }. A List<Shape> holding new Rect(2, 3) and new Circle(1) can total areas in one loop: 6 + 3.14159... = about 9.14.
Key takeaways
extends creates subclasses; Java has single class inheritance, and all classes descend from Object. @Override marks overriding; super calls the parent. Polymorphism picks the method of the actual object at run time. Abstract classes cannot be instantiated and can force subclasses to implement methods. Interfaces declare capabilities; a class can implement many. Exceptions use try, catch, finally, and try-with-resources. Checked exceptions must be handled or declared; unchecked ones signal bugs.
Flashcard
Creates a subclass
Check your understanding
Why might a Java class implement several interfaces when it can extend only one class?
