The constructor chain

java
public class Animal {
    private String name;
    
    public Animal(String name) {
        this.name = name;
        System.out.println("Animal constructor: " + name);
    }
}

public class Dog extends Animal {
    private String breed;
    
    public Dog(String name, String breed) {
        super(name);  // Animal constructor runs first
        this.breed = breed;
        System.out.println("Dog constructor: " + breed);
    }
}

public class GuideDog extends Dog {
    private String owner;
    
    public GuideDog(String name, String breed, String owner) {
        super(name, breed);  // Dog constructor runs first
        this.owner = owner;
        System.out.println("GuideDog constructor: " + owner);
    }
}
java
GuideDog g = new GuideDog("Rex", "Lab", "Alice");
Animal constructor: Rex
Dog constructor: Lab
GuideDog constructor: Alice

Rules for `super()`

Rule 1: Must be the first statement

java
public Dog(String name, String breed) {
    this.breed = breed;  // COMPILE ERROR — super() must come first
    super(name);
}

Rule 2: Implicit `super()` if omitted

java
public class Pet extends Animal {
    public Pet() {
        // Java inserts: super();  ← calls Animal()
        // If Animal has no no-arg constructor → COMPILE ERROR
    }
}

Rule 3: Match the superclass constructor signature

java
public class Animal {
    public Animal(String name) { }   // only constructor
}

public class Cat extends Animal {
    public Cat() {
        // implicitly calls super() — but Animal() doesn't exist!
        // COMPILE ERROR
    }
    
    public Cat(String name) {
        super(name);  // OK — matches Animal(String)
    }
}

Multiple constructors in subclass

java
public class Student extends Person {
    private int grade;
    
    // Constructor 1: full info
    public Student(String name, int age, int grade) {
        super(name, age);
        this.grade = grade;
    }
    
    // Constructor 2: default grade
    public Student(String name, int age) {
        super(name, age);
        this.grade = 9;  // default to freshman
    }
    
    // Constructor 3: using this()
    public Student(String name) {
        this(name, 14, 9);  // calls Constructor 1
    }
}

What the subclass constructor does NOT do

java
public class Dog extends Animal {
    public Dog(String name) {
        // this.name = name;  // COMPILE ERROR — name is private to Animal
        super(name);           // Let Animal initialize its own field
    }
}

Trace: Constructor execution order

java
public class A {
    public A() {
        System.out.println("A");
    }
}

public class B extends A {
    public B() {
        super();  // explicit, but Java would add this anyway
        System.out.println("B");
    }
}

public class C extends B {
    public C() {
        System.out.println("C");
    }
}
java
C obj = new C();

Overriding methods

java
public class Shape {
    public double area() {
        return 0;
    }
    
    public String toString() {
        return "Shape with area " + area();
    }
}

public class Circle extends Shape {
    private double radius;
    
    public Circle(double radius) {
        this.radius = radius;
    }
    
    @Override
    public double area() {
        return Math.PI * radius * radius;
    }
    
    @Override
    public String toString() {
        return "Circle (r=" + radius + ", area=" 
            + String.format("%.2f", area()) + ")";
    }
}

Override rules

Overriding vs. overloading

java
// OVERRIDING — same signature, different class
class Animal {
    public String speak() { return "..."; }
}
class Dog extends Animal {
    public String speak() { return "Woof!"; }  // overrides
}

// OVERLOADING — different parameters, same class
class Calculator {
    public int add(int a, int b) { return a + b; }
    public double add(double a, double b) { return a + b; }  // overloads
}

Using `super.method()` from an override

java
public class Manager extends Employee {
    private double bonus;
    
    public Manager(String name, double salary, double bonus) {
        super(name, salary);
        this.bonus = bonus;
    }
    
    @Override
    public double annualPay() {
        return super.annualPay() + bonus;  // parent's pay + bonus
    }
}

Complete example: Shape hierarchy

java
public class Shape {
    private String color;
    
    public Shape(String color) {
        this.color = color;
    }
    
    public String getColor() { return color; }
    
    public double area() { return 0; }
    
    public String toString() {
        return color + " shape (area: " 
            + String.format("%.2f", area()) + ")";
    }
}

public class Rectangle extends Shape {
    private double width, height;
    
    public Rectangle(String color, double width, double height) {
        super(color);
        this.width = width;
        this.height = height;
    }
    
    @Override
    public double area() {
        return width * height;
    }
    
    @Override
    public String toString() {
        return getColor() + " rectangle " + width + "×" + height
            + " (area: " + String.format("%.2f", area()) + ")";
    }
}

public class Square extends Rectangle {
    public Square(String color, double side) {
        super(color, side, side);  // a square is a rectangle with equal sides
    }
    
    @Override
    public String toString() {
        return getColor() + " square (area: " 
            + String.format("%.2f", area()) + ")";
    }
}
java
Shape s = new Shape("gray");
Rectangle r = new Rectangle("blue", 4, 3);
Square sq = new Square("red", 5);

System.out.println(s);   // gray shape (area: 0.00)
System.out.println(r);   // blue rectangle 4.0×3.0 (area: 12.00)
System.out.println(sq);  // red square (area: 25.00)

AP Exam Tips

Common Mistakes

Key Vocabulary