Java Cheatsheet
Inheritance and Interfaces
Use this Java reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.
extends — Class Inheritance
Java supports single class inheritance.
public class Animal { protected String name; private int age; public Animal(String name, int age) { this.name = name; this.age = age; } public void speak() { System.out.println(name + " makes a sound."); } public int getAge() { return age; } @Override public String toString() { return name + " (age " + age + ")"; } } public class Dog extends Animal { private String breed; public Dog(String name, int age, String breed) { super(name, age); // must be FIRST statement in constructor this.breed = breed; } @Override public void speak() { System.out.println(name + " barks!"); } public String getBreed() { return breed; } } Dog d = new Dog("Rex", 3, "Labrador"); d.speak(); // "Rex barks!" — overridden d.getAge(); // 3 — inherited d instanceof Animal // true d instanceof Dog // true
Method Overriding
class Shape { public double area() { return 0; } } class Circle extends Shape { private double r; Circle(double r) { this.r = r; } @Override // annotation enforced by compiler — catches typos public double area() { return Math.PI * r * r; } }
Rules for overriding:
- Same name, same parameter types (same signature).
- Return type must be the same or a covariant (narrower) subtype.
- Access modifier must be the same or less restrictive.
- Cannot throw broader checked exceptions.
- Cannot override static, final, or private methods.
super Keyword
class Parent { String greet() { return "Hello from Parent"; } } class Child extends Parent { @Override String greet() { return super.greet() + " and Child"; // call parent version } Child() { super(); // implicit if omitted and parent has no-arg ctor } }
super — accesses parent class fields, methods, or constructor.
super.method() — calls parent's version of an instance method.
super(args) — calls parent constructor (must be first line).
Abstract Classes
public abstract class Shape { abstract double area(); // no body — subclass must implement abstract double perimeter(); // Can have concrete methods public void describe() { System.out.printf("Area=%.2f, Perimeter=%.2f%n", area(), perimeter()); } // Can have constructors, fields, static members protected String color = "black"; } public class Square extends Shape { private double side; Square(double side) { this.side = side; } @Override double area() { return side * side; } @Override double perimeter() { return 4 * side; } } // Cannot instantiate abstract class: // new Shape(); // compile error
Interfaces
public interface Drawable { void draw(); // abstract (always public) double getArea(); // Default method (Java 8+) — has a body, can be overridden default String description() { return "A drawable with area " + getArea(); } // Static method (Java 8+) — called on the interface, not instances static Drawable empty() { return () -> {}; } // Constants int VERSION = 1; // implicitly public static final } // Implementing an interface public class Circle implements Drawable { private double radius; Circle(double r) { this.radius = r; } @Override public void draw() { System.out.println("drawing circle"); } @Override public double getArea() { return Math.PI * radius * radius; } }
Implementing Multiple Interfaces
interface Flyable { void fly(); } interface Swimmable { void swim(); } class Duck extends Animal implements Flyable, Swimmable { @Override public void fly() { System.out.println("Duck flying"); } @Override public void swim() { System.out.println("Duck swimming"); } }
Interface Default Method Conflict Resolution
interface A { default void greet() { System.out.println("A"); } } interface B { default void greet() { System.out.println("B"); } } class C implements A, B { @Override public void greet() { A.super.greet(); // explicitly choose which default to call } }
Interface vs. Abstract Class
| Feature | Abstract Class | Interface |
|---|---|---|
| Multiple inheritance | No (single extends) | Yes (implements many) |
| Constructors | Yes | No |
| Instance fields | Yes | No (constants only) |
| Method bodies | Yes | Only default and static |
| Access modifiers on methods | Any | Always public (abstract) |
| Use when | IS-A + shared state | CAN-DO capability contract |
Polymorphism
// Runtime dispatch (dynamic binding) Shape s = new Circle(5.0); // compile-type Shape, runtime Circle s.area(); // calls Circle.area() — virtual dispatch // Collections of mixed subtypes List<Shape> shapes = new ArrayList<>(); shapes.add(new Circle(3)); shapes.add(new Square(4)); shapes.add(new Triangle(3, 4, 5)); for (Shape shape : shapes) { shape.describe(); // each calls its own area() and perimeter() }
final Keyword
final class Immutable { ... } // cannot be subclassed final void doIt() { ... } // cannot be overridden final int MAX = 100; // constant field
Sealed Classes and Interfaces (Java 17+)
sealed interface Expr permits Num, Add, Mul {} record Num(int value) implements Expr {} record Add(Expr left, Expr right) implements Expr {} record Mul(Expr left, Expr right) implements Expr {} // Exhaustive pattern switch (Java 21+) int eval(Expr e) { return switch (e) { case Num(int v) -> v; case Add(Expr l, Expr r) -> eval(l) + eval(r); case Mul(Expr l, Expr r) -> eval(l) * eval(r); }; }
Permitted subclasses must be in the same package (or module). Subclasses must be final, sealed, or non-sealed.
Casting and instanceof with Inheritance
Animal a = new Dog("Rex", 3, "Lab"); // Upcast (always safe, implicit) Animal ref = new Dog("Rex", 3, "Lab"); // Downcast (requires explicit cast; fails at runtime if wrong) Dog d = (Dog) ref; // OK if ref actually holds a Dog Cat c = (Cat) ref; // ClassCastException! // Safe downcast pattern if (ref instanceof Dog dog) { // pattern matching (Java 16+) dog.getBreed(); }
Interfaces as Types
// Use interface type to decouple List<Integer> list = new ArrayList<>(); // interface = List, impl = ArrayList Comparator<String> cmp = String::compareToIgnoreCase; Iterable<String> iter = Set.of("a","b"); // Method accepting interface type public static void printAll(Iterable<?> items) { for (var item : items) System.out.println(item); } printAll(List.of(1,2,3)); printAll(Set.of("x","y"));
Functional Interfaces and Inheritance
// A @FunctionalInterface can extend another, as long as no new abstract method is added @FunctionalInterface interface StringMapper extends Function<String, String> {} StringMapper upper = String::toUpperCase;
Marker Interfaces
Interfaces with no methods — signal a capability to the JVM or frameworks.
Serializable // java.io — object can be serialized Cloneable // java.lang — clone() is allowed RandomAccess // java.util — list supports O(1) get Remote // java.rmi — object can be used remotely
Constructor Chaining with Inheritance
class Vehicle { String brand; Vehicle(String brand) { this.brand = brand; } } class Car extends Vehicle { int doors; Car(String brand, int doors) { super(brand); // super() call must be first this.doors = doors; } } class ElectricCar extends Car { int range; ElectricCar(String brand, int doors, int range) { super(brand, doors); // chains to Car constructor this.range = range; } }
Practical Patterns
// Template Method Pattern — define skeleton, subclasses fill in steps abstract class DataProcessor { final void process() { // final: subclasses can't change the flow readData(); processData(); writeData(); } abstract void readData(); abstract void processData(); abstract void writeData(); } // Strategy Pattern via interface interface SortStrategy { void sort(int[] arr); } class BubbleSort implements SortStrategy { @Override public void sort(int[] arr) { /* bubble sort */ } } class QuickSort implements SortStrategy { @Override public void sort(int[] arr) { /* quick sort */ } } class Sorter { private SortStrategy strategy; Sorter(SortStrategy s) { this.strategy = s; } void sort(int[] arr) { strategy.sort(arr); } }