Your payment system accepts CreditCard, PayPal, and BankTransfer. Instead of separate code paths for each, polymorphism lets you treat them all as Payment objects - calling process() works correctly for each type.

Runtime polymorphism

Parent reference can hold child object.

choice
Runtime.java
Replay: real traced execution (multi-file project)
// Runtime Polymorphism

public class Runtime {
    public static void main(String[] args) {
        System.out.println("=== Runtime Polymorphism ===\n");

        // Same type reference, different objects
        Animal a1 = new Dog();
        Animal a2 = new Cat();
        Animal a3 = new Bird();

        // Each calls its OWN version of makeSound()
        System.out.println("Calling makeSound() on each:");
        a1.makeSound();  // Woof!
        a2.makeSound();  // Meow!
        a3.makeSound();  // Tweet!

        System.out.println("\n=== Why 'Polymorphism'? ===");
        System.out.println("""
        Poly = Many
        Morph = Forms

        Same method name (makeSound)
        Many different behaviors (woof, meow, tweet)
        """);

        System.out.println("=== Method Called at Runtime ===");

        // The actual method called depends on the OBJECT
        int choice = 0;
        Animal mystery = getAnimal(choice);
        System.out.println("Mystery animal says:");
        mystery.makeSound();  // Which version? Depends on actual object!
    }

    static Animal getAnimal(int choice) {
        return switch(choice) {
            case 0 -> new Dog();
            case 1 -> new Cat();
            default -> new Bird();
        };
    }
}

class Animal {
    void makeSound() {
        System.out.println("Some generic sound");
    }
}

class Dog extends Animal {
    @Override
    void makeSound() {
        System.out.println("Woof! Woof!");
    }
}

class Cat extends Animal {
    @Override
    void makeSound() {
        System.out.println("Meow!");
    }
}

class Bird extends Animal {
    @Override
    void makeSound() {
        System.out.println("Tweet! Tweet!");
    }
}

// Runtime Polymorphism

public class Runtime {
    public static void main(String[] args) {
        System.out.println("=== Runtime Polymorphism ===\n");

        // Same type reference, different objects
        Animal a1 = new Dog();
        Animal a2 = new Cat();
        Animal a3 = new Bird();

        // Each calls its OWN version of makeSound()
        System.out.println("Calling makeSound() on each:");
        a1.makeSound();  // Woof!
        a2.makeSound();  // Meow!
        a3.makeSound();  // Tweet!

        System.out.println("\n=== Why 'Polymorphism'? ===");
        System.out.println("""
        Poly = Many
        Morph = Forms

        Same method name (makeSound)
        Many different behaviors (woof, meow, tweet)
        """);

        System.out.println("=== Method Called at Runtime ===");

        // The actual method called depends on the OBJECT
        int choice = 1;
        Animal mystery = getAnimal(choice);
        System.out.println("Mystery animal says:");
        mystery.makeSound();  // Which version? Depends on actual object!
    }

    static Animal getAnimal(int choice) {
        return switch(choice) {
            case 0 -> new Dog();
            case 1 -> new Cat();
            default -> new Bird();
        };
    }
}

class Animal {
    void makeSound() {
        System.out.println("Some generic sound");
    }
}

class Dog extends Animal {
    @Override
    void makeSound() {
        System.out.println("Woof! Woof!");
    }
}

class Cat extends Animal {
    @Override
    void makeSound() {
        System.out.println("Meow!");
    }
}

class Bird extends Animal {
    @Override
    void makeSound() {
        System.out.println("Tweet! Tweet!");
    }
}

// Runtime Polymorphism

public class Runtime {
    public static void main(String[] args) {
        System.out.println("=== Runtime Polymorphism ===\n");

        // Same type reference, different objects
        Animal a1 = new Dog();
        Animal a2 = new Cat();
        Animal a3 = new Bird();

        // Each calls its OWN version of makeSound()
        System.out.println("Calling makeSound() on each:");
        a1.makeSound();  // Woof!
        a2.makeSound();  // Meow!
        a3.makeSound();  // Tweet!

        System.out.println("\n=== Why 'Polymorphism'? ===");
        System.out.println("""
        Poly = Many
        Morph = Forms

        Same method name (makeSound)
        Many different behaviors (woof, meow, tweet)
        """);

        System.out.println("=== Method Called at Runtime ===");

        // The actual method called depends on the OBJECT
        int choice = 2;
        Animal mystery = getAnimal(choice);
        System.out.println("Mystery animal says:");
        mystery.makeSound();  // Which version? Depends on actual object!
    }

    static Animal getAnimal(int choice) {
        return switch(choice) {
            case 0 -> new Dog();
            case 1 -> new Cat();
            default -> new Bird();
        };
    }
}

class Animal {
    void makeSound() {
        System.out.println("Some generic sound");
    }
}

class Dog extends Animal {
    @Override
    void makeSound() {
        System.out.println("Woof! Woof!");
    }
}

class Cat extends Animal {
    @Override
    void makeSound() {
        System.out.println("Meow!");
    }
}

class Bird extends Animal {
    @Override
    void makeSound() {
        System.out.println("Tweet! Tweet!");
    }
}

  1. a1 ← ⟨Dog A⟩, a2 ← ⟨Cat B⟩, a3 ← ⟨Bird C⟩

    3public class Runtime {4    public static void main(String[] args) {5        System.out.println("=== Runtime Polymorphism ===\n");6        7        // Same type reference, different objects  //?sameref8        Animal a1→ ⟨Dog A⟩ = new Dog();    //?dogasanimal9        Animal a2→ ⟨Cat B⟩ = new Cat();    //?catasanimal10        Animal a3→ ⟨Bird C⟩ = new Bird();11        12        // Each calls its OWN version of makeSound()  //?owncall13        System.out.println("Calling makeSound() on each:");14        a1.makeSound();  // Woof!15        a2.makeSound();  // Meow!
    output=== Runtime Polymorphism ===
    Calling makeSound() on each:
  2. @Override void makeSound()

    pass 1 of 2
    13        System.out.println("Calling makeSound() on each:");14        a1.makeSound();  // Woof!15        a2.makeSound();  // Meow!16        a3.makeSound();  // Tweet!17        18        System.out.println("\n=== Why 'Polymorphism'? ===");19        System.out.println("""20        Poly = Many21        Morph = Forms22        23        Same method name (makeSound)24        Many different behaviors (woof, meow, tweet)25        """);26        27        System.out.println("=== Method Called at Runtime ===");28        29        // The actual method called depends on the OBJECT  //?runtime30        int choice = 0;  //@choice=1, 231        Animal mystery = getAnimal(choice);32        System.out.println("Mystery animal says:");33        mystery.makeSound();  // Which version? Depends on actual object!  //?mystery34    }35    36    static Animal getAnimal(int choice) {  //?factory37        return switch(choice) {38            case 0 -> new Dog();39            case 1 -> new Cat();40            default -> new Bird();41        };42    }43}4445class Animal {46    void makeSound() {47        System.out.println("Some generic sound");48    }49}5051class Dog extends Animal {52    @Override53    void makeSound() {  //?dogoverride54        System.out.println("Woof! Woof!");55    }
    outputWoof! Woof!
  3. @Override void makeSound()

    14        a1.makeSound();  // Woof!15        a2.makeSound();  // Meow!16        a3.makeSound();  // Tweet!17        18        System.out.println("\n=== Why 'Polymorphism'? ===");19        System.out.println("""20        Poly = Many21        Morph = Forms22        23        Same method name (makeSound)24        Many different behaviors (woof, meow, tweet)25        """);26        27        System.out.println("=== Method Called at Runtime ===");28        29        // The actual method called depends on the OBJECT  //?runtime30        int choice = 0;  //@choice=1, 231        Animal mystery = getAnimal(choice);32        System.out.println("Mystery animal says:");33        mystery.makeSound();  // Which version? Depends on actual object!  //?mystery34    }35    36    static Animal getAnimal(int choice) {  //?factory37        return switch(choice) {38            case 0 -> new Dog();39            case 1 -> new Cat();40            default -> new Bird();41        };42    }43}4445class Animal {46    void makeSound() {47        System.out.println("Some generic sound");48    }49}5051class Dog extends Animal {52    @Override53    void makeSound() {  //?dogoverride54        System.out.println("Woof! Woof!");55    }56}5758class Cat extends Animal {59    @Override60    void makeSound() {  //?catoverride61        System.out.println("Meow!");62    }
    outputMeow!
  4. choice ← 0

    15        a2.makeSound();  // Meow!16        a3.makeSound();  // Tweet!17        18        System.out.println("\n=== Why 'Polymorphism'? ===");19        System.out.println("""20        Poly = Many21        Morph = Forms22        23        Same method name (makeSound)24        Many different behaviors (woof, meow, tweet)25        """);26        27        System.out.println("=== Method Called at Runtime ===");28        29        // The actual method called depends on the OBJECT  //?runtime30        int choice→ 0 = 0;  //@choice=1, 231        Animal mystery = getAnimal(choice0);32        System.out.println("Mystery animal says:");33        mystery.makeSound();  // Which version? Depends on actual object!  //?mystery34    }35    36    static Animal getAnimal(int choice) {  //?factory37        return switch(choice) {38            case 0 -> new Dog();39            case 1 -> new Cat();40            default -> new Bird();41        };42    }43}4445class Animal {46    void makeSound() {47        System.out.println("Some generic sound");48    }49}5051class Dog extends Animal {52    @Override53    void makeSound() {  //?dogoverride54        System.out.println("Woof! Woof!");55    }56}5758class Cat extends Animal {59    @Override60    void makeSound() {  //?catoverride61        System.out.println("Meow!");62    }63}6465class Bird extends Animal {66    @Override67    void makeSound() {68        System.out.println("Tweet! Tweet!");69    }
    outputTweet! Tweet!
    
    === Why 'Polymorphism'? ===
    Poly = Many
    Morph = Forms
    
    Same method name (makeSound)
    Many different behaviors (woof, meow, tweet)
    === Method Called at Runtime ===
  5. static Animal getAnimal(int choice)

    36static Animal getAnimal(int choice0) {  //?factory37    return switch(choice) {38        case 0 -> new Dog();39        case 1 -> new Cat();40        default -> new Bird();41    };42}
  6. mystery ← ⟨Dog D⟩

    30    int choice = 0;  //@choice=1, 231    Animal mystery→ ⟨Dog D⟩ = getAnimal(choice0);32    System.out.println("Mystery animal says:");33    mystery.makeSound();  // Which version? Depends on actual object!  //?mystery34}
    outputMystery animal says:
  7. @Override void makeSound()

    pass 2 of 2
    32        System.out.println("Mystery animal says:");33        mystery.makeSound();  // Which version? Depends on actual object!  //?mystery34    }35    36    static Animal getAnimal(int choice) {  //?factory37        return switch(choice) {38            case 0 -> new Dog();39            case 1 -> new Cat();40            default -> new Bird();41        };42    }43}4445class Animal {46    void makeSound() {47        System.out.println("Some generic sound");48    }49}5051class Dog extends Animal {52    @Override53    void makeSound() {  //?dogoverride54        System.out.println("Woof! Woof!");55    }
    outputWoof! Woof!
  1. a1 ← ⟨Dog A⟩, a2 ← ⟨Cat B⟩, a3 ← ⟨Bird C⟩

    3public class Runtime {4    public static void main(String[] args) {5        System.out.println("=== Runtime Polymorphism ===\n");6        7        // Same type reference, different objects8        Animal a1→ ⟨Dog A⟩ = new Dog();9        Animal a2→ ⟨Cat B⟩ = new Cat();10        Animal a3→ ⟨Bird C⟩ = new Bird();11        12        // Each calls its OWN version of makeSound()13        System.out.println("Calling makeSound() on each:");14        a1.makeSound();  // Woof!15        a2.makeSound();  // Meow!
    output=== Runtime Polymorphism ===
    Calling makeSound() on each:
  2. @Override void makeSound()

    13        System.out.println("Calling makeSound() on each:");14        a1.makeSound();  // Woof!15        a2.makeSound();  // Meow!16        a3.makeSound();  // Tweet!17        18        System.out.println("\n=== Why 'Polymorphism'? ===");19        System.out.println("""20        Poly = Many21        Morph = Forms22        23        Same method name (makeSound)24        Many different behaviors (woof, meow, tweet)25        """);26        27        System.out.println("=== Method Called at Runtime ===");28        29        // The actual method called depends on the OBJECT30        int choice = 1;31        Animal mystery = getAnimal(choice);32        System.out.println("Mystery animal says:");33        mystery.makeSound();  // Which version? Depends on actual object!34    }35    36    static Animal getAnimal(int choice) {37        return switch(choice) {38            case 0 -> new Dog();39            case 1 -> new Cat();40            default -> new Bird();41        };42    }43}4445class Animal {46    void makeSound() {47        System.out.println("Some generic sound");48    }49}5051class Dog extends Animal {52    @Override53    void makeSound() {54        System.out.println("Woof! Woof!");55    }
    outputWoof! Woof!
  3. @Override void makeSound()

    pass 1 of 2
    14        a1.makeSound();  // Woof!15        a2.makeSound();  // Meow!16        a3.makeSound();  // Tweet!17        18        System.out.println("\n=== Why 'Polymorphism'? ===");19        System.out.println("""20        Poly = Many21        Morph = Forms22        23        Same method name (makeSound)24        Many different behaviors (woof, meow, tweet)25        """);26        27        System.out.println("=== Method Called at Runtime ===");28        29        // The actual method called depends on the OBJECT30        int choice = 1;31        Animal mystery = getAnimal(choice);32        System.out.println("Mystery animal says:");33        mystery.makeSound();  // Which version? Depends on actual object!34    }35    36    static Animal getAnimal(int choice) {37        return switch(choice) {38            case 0 -> new Dog();39            case 1 -> new Cat();40            default -> new Bird();41        };42    }43}4445class Animal {46    void makeSound() {47        System.out.println("Some generic sound");48    }49}5051class Dog extends Animal {52    @Override53    void makeSound() {54        System.out.println("Woof! Woof!");55    }56}5758class Cat extends Animal {59    @Override60    void makeSound() {61        System.out.println("Meow!");62    }
    outputMeow!
  4. choice ← 1

    15        a2.makeSound();  // Meow!16        a3.makeSound();  // Tweet!17        18        System.out.println("\n=== Why 'Polymorphism'? ===");19        System.out.println("""20        Poly = Many21        Morph = Forms22        23        Same method name (makeSound)24        Many different behaviors (woof, meow, tweet)25        """);26        27        System.out.println("=== Method Called at Runtime ===");28        29        // The actual method called depends on the OBJECT30        int choice→ 1 = 1;31        Animal mystery = getAnimal(choice1);32        System.out.println("Mystery animal says:");33        mystery.makeSound();  // Which version? Depends on actual object!34    }35    36    static Animal getAnimal(int choice) {37        return switch(choice) {38            case 0 -> new Dog();39            case 1 -> new Cat();40            default -> new Bird();41        };42    }43}4445class Animal {46    void makeSound() {47        System.out.println("Some generic sound");48    }49}5051class Dog extends Animal {52    @Override53    void makeSound() {54        System.out.println("Woof! Woof!");55    }56}5758class Cat extends Animal {59    @Override60    void makeSound() {61        System.out.println("Meow!");62    }63}6465class Bird extends Animal {66    @Override67    void makeSound() {68        System.out.println("Tweet! Tweet!");69    }
    outputTweet! Tweet!
    
    === Why 'Polymorphism'? ===
    Poly = Many
    Morph = Forms
    
    Same method name (makeSound)
    Many different behaviors (woof, meow, tweet)
    === Method Called at Runtime ===
  5. static Animal getAnimal(int choice)

    36static Animal getAnimal(int choice1) {37    return switch(choice) {38        case 0 -> new Dog();39        case 1 -> new Cat();40        default -> new Bird();41    };42}
  6. mystery ← ⟨Cat D⟩

    30    int choice = 1;31    Animal mystery→ ⟨Cat D⟩ = getAnimal(choice1);32    System.out.println("Mystery animal says:");33    mystery.makeSound();  // Which version? Depends on actual object!34}
    outputMystery animal says:
  7. @Override void makeSound()

    pass 2 of 2
    32        System.out.println("Mystery animal says:");33        mystery.makeSound();  // Which version? Depends on actual object!34    }35    36    static Animal getAnimal(int choice) {37        return switch(choice) {38            case 0 -> new Dog();39            case 1 -> new Cat();40            default -> new Bird();41        };42    }43}4445class Animal {46    void makeSound() {47        System.out.println("Some generic sound");48    }49}5051class Dog extends Animal {52    @Override53    void makeSound() {54        System.out.println("Woof! Woof!");55    }56}5758class Cat extends Animal {59    @Override60    void makeSound() {61        System.out.println("Meow!");62    }
    outputMeow!
  1. a1 ← ⟨Dog A⟩, a2 ← ⟨Cat B⟩, a3 ← ⟨Bird C⟩

    3public class Runtime {4    public static void main(String[] args) {5        System.out.println("=== Runtime Polymorphism ===\n");6        7        // Same type reference, different objects8        Animal a1→ ⟨Dog A⟩ = new Dog();9        Animal a2→ ⟨Cat B⟩ = new Cat();10        Animal a3→ ⟨Bird C⟩ = new Bird();11        12        // Each calls its OWN version of makeSound()13        System.out.println("Calling makeSound() on each:");14        a1.makeSound();  // Woof!15        a2.makeSound();  // Meow!
    output=== Runtime Polymorphism ===
    Calling makeSound() on each:
  2. @Override void makeSound()

    13        System.out.println("Calling makeSound() on each:");14        a1.makeSound();  // Woof!15        a2.makeSound();  // Meow!16        a3.makeSound();  // Tweet!17        18        System.out.println("\n=== Why 'Polymorphism'? ===");19        System.out.println("""20        Poly = Many21        Morph = Forms22        23        Same method name (makeSound)24        Many different behaviors (woof, meow, tweet)25        """);26        27        System.out.println("=== Method Called at Runtime ===");28        29        // The actual method called depends on the OBJECT30        int choice = 2;31        Animal mystery = getAnimal(choice);32        System.out.println("Mystery animal says:");33        mystery.makeSound();  // Which version? Depends on actual object!34    }35    36    static Animal getAnimal(int choice) {37        return switch(choice) {38            case 0 -> new Dog();39            case 1 -> new Cat();40            default -> new Bird();41        };42    }43}4445class Animal {46    void makeSound() {47        System.out.println("Some generic sound");48    }49}5051class Dog extends Animal {52    @Override53    void makeSound() {54        System.out.println("Woof! Woof!");55    }
    outputWoof! Woof!
  3. @Override void makeSound()

    14        a1.makeSound();  // Woof!15        a2.makeSound();  // Meow!16        a3.makeSound();  // Tweet!17        18        System.out.println("\n=== Why 'Polymorphism'? ===");19        System.out.println("""20        Poly = Many21        Morph = Forms22        23        Same method name (makeSound)24        Many different behaviors (woof, meow, tweet)25        """);26        27        System.out.println("=== Method Called at Runtime ===");28        29        // The actual method called depends on the OBJECT30        int choice = 2;31        Animal mystery = getAnimal(choice);32        System.out.println("Mystery animal says:");33        mystery.makeSound();  // Which version? Depends on actual object!34    }35    36    static Animal getAnimal(int choice) {37        return switch(choice) {38            case 0 -> new Dog();39            case 1 -> new Cat();40            default -> new Bird();41        };42    }43}4445class Animal {46    void makeSound() {47        System.out.println("Some generic sound");48    }49}5051class Dog extends Animal {52    @Override53    void makeSound() {54        System.out.println("Woof! Woof!");55    }56}5758class Cat extends Animal {59    @Override60    void makeSound() {61        System.out.println("Meow!");62    }
    outputMeow!
  4. choice ← 2

    pass 1 of 2
    15        a2.makeSound();  // Meow!16        a3.makeSound();  // Tweet!17        18        System.out.println("\n=== Why 'Polymorphism'? ===");19        System.out.println("""20        Poly = Many21        Morph = Forms22        23        Same method name (makeSound)24        Many different behaviors (woof, meow, tweet)25        """);26        27        System.out.println("=== Method Called at Runtime ===");28        29        // The actual method called depends on the OBJECT30        int choice→ 2 = 2;31        Animal mystery = getAnimal(choice2);32        System.out.println("Mystery animal says:");33        mystery.makeSound();  // Which version? Depends on actual object!34    }35    36    static Animal getAnimal(int choice) {37        return switch(choice) {38            case 0 -> new Dog();39            case 1 -> new Cat();40            default -> new Bird();41        };42    }43}4445class Animal {46    void makeSound() {47        System.out.println("Some generic sound");48    }49}5051class Dog extends Animal {52    @Override53    void makeSound() {54        System.out.println("Woof! Woof!");55    }56}5758class Cat extends Animal {59    @Override60    void makeSound() {61        System.out.println("Meow!");62    }63}6465class Bird extends Animal {66    @Override67    void makeSound() {68        System.out.println("Tweet! Tweet!");69    }
    outputTweet! Tweet!
    
    === Why 'Polymorphism'? ===
    Poly = Many
    Morph = Forms
    
    Same method name (makeSound)
    Many different behaviors (woof, meow, tweet)
    === Method Called at Runtime ===
  5. static Animal getAnimal(int choice)

    36static Animal getAnimal(int choice2) {37    return switch(choice) {38        case 0 -> new Dog();39        case 1 -> new Cat();40        default -> new Bird();41    };42}
  6. mystery ← ⟨Bird D⟩

    30    int choice = 2;31    Animal mystery→ ⟨Bird D⟩ = getAnimal(choice2);32    System.out.println("Mystery animal says:");33    mystery.makeSound();  // Which version? Depends on actual object!34}
    outputMystery animal says:
  7. @Override void makeSound()

    pass 2 of 2
    32        System.out.println("Mystery animal says:");33        mystery.makeSound();  // Which version? Depends on actual object!34    }35    36    static Animal getAnimal(int choice) {37        return switch(choice) {38            case 0 -> new Dog();39            case 1 -> new Cat();40            default -> new Bird();41        };42    }43}4445class Animal {46    void makeSound() {47        System.out.println("Some generic sound");48    }49}5051class Dog extends Animal {52    @Override53    void makeSound() {54        System.out.println("Woof! Woof!");55    }56}5758class Cat extends Animal {59    @Override60    void makeSound() {61        System.out.println("Meow!");62    }63}6465class Bird extends Animal {66    @Override67    void makeSound() {68        System.out.println("Tweet! Tweet!");69    }
    outputTweet! Tweet!

Animal a = new Dog() - variable type is Animal, object is Dog.

polymorphism Same code works with different types. Parent reference, child behavior.

Parent reference to child

Store different subtypes in parent-type variable.

ParentReference.java
Replay: real traced execution (multi-file project)
// Using Parent Type to Reference Child Objects

public class ParentReference {
    public static void main(String[] args) {
        System.out.println("=== Parent Reference, Child Object ===\n");

        // Different declaration styles
        Dog dog = new Dog("Buddy");
        Animal animal = new Dog("Max");

        // Both work for inherited methods
        System.out.println("Both can make sounds:");
        dog.makeSound();
        animal.makeSound();

        System.out.println("\n=== Access Differences ===");

        // Dog reference: full access
        dog.makeSound();   // OK - inherited
        dog.fetch();       // OK - Dog-specific

        // Animal reference: limited access
        animal.makeSound();  // OK - defined in Animal
        // animal.fetch();   // ERROR! Animal doesn't know about fetch

        System.out.println("\n=== Why Use Parent Reference? ===");

        // Flexibility: accept any animal
        feedAnimal(new Dog("Rex"));
        feedAnimal(new Cat("Whiskers"));

        System.out.println("\n=== Upcasting (Automatic) ===");

        Dog rex = new Dog("Rex");
        Animal asAnimal = rex;
        System.out.println("Upcasted: Dog → Animal");

        System.out.println("\n=== Downcasting (Manual) ===");

        Animal mystery = new Dog("Scout");
        Dog backToDog = (Dog) mystery;
        backToDog.fetch();  // Now we can call fetch!
        System.out.println("Downcasted: Animal → Dog");
    }

    // Method accepts ANY Animal
    static void feedAnimal(Animal a) {
        System.out.println("Feeding the animal...");
        a.makeSound();  // Works for any animal type
    }
}

class Animal {
    String name;

    Animal(String name) {
        this.name = name;
    }

    void makeSound() {
        System.out.println(name + " makes a sound");
    }
}

class Dog extends Animal {
    Dog(String name) {
        super(name);
    }

    @Override
    void makeSound() {
        System.out.println(name + " barks: Woof!");
    }

    void fetch() {
        System.out.println(name + " fetches the ball!");
    }
}

class Cat extends Animal {
    Cat(String name) {
        super(name);
    }

    @Override
    void makeSound() {
        System.out.println(name + " meows: Meow!");
    }
}

  1. public static void main(String[] args)

    3public class ParentReference {4    public static void main(String[] args) {5        System.out.println("=== Parent Reference, Child Object ===\n");6        7        // Different declaration styles  //?styles8        Dog dog = new Dog("Buddy");           //?dogref9        Animal animal = new Dog("Max");        //?animalref
    output=== Parent Reference, Child Object ===
  2. this.name ← Buddy

    pass 1 of 6
    56Animal(String nameBuddy) {57    this.name→ Buddy = nameBuddy;58}
    All 6 passes — pass 1 is the card above
    passnameathis.name
    1BuddyBuddy
    2MaxMax
    3Rex⟨Dog A⟩Rex
    4Whiskers⟨Cat B⟩Whiskers
    5RexRex
    6ScoutScout
  3. dog ← ⟨Dog C⟩

    pass 1 of 5
    7        // Different declaration styles  //?styles8        Dog dog→ ⟨Dog C⟩ = new Dog("Buddy");           //?dogref9        Animal animal = new Dog("Max");        //?animalref10        11        // Both work for inherited methods12        System.out.println("Both can make sounds:");13        dog.makeSound();14        animal.makeSound();15        16        System.out.println("\n=== Access Differences ===");17        18        // Dog reference: full access  //?fullaccess19        dog.makeSound();   // OK - inherited20        dog.fetch();       // OK - Dog-specific21        22        // Animal reference: limited access  //?limited23        animal.makeSound();  // OK - defined in Animal24        // animal.fetch();   // ERROR! Animal doesn't know about fetch  //?nofetch25        26        System.out.println("\n=== Why Use Parent Reference? ===");27        28        // Flexibility: accept any animal  //?flexibility29        feedAnimal(new Dog("Rex"));30        feedAnimal(new Cat("Whiskers"));31        32        System.out.println("\n=== Upcasting (Automatic) ===");33        34        Dog rex = new Dog("Rex");35        Animal asAnimal = rex;  //?upcast36        System.out.println("Upcasted: Dog → Animal");37        38        System.out.println("\n=== Downcasting (Manual) ===");39        40        Animal mystery = new Dog("Scout");41        Dog backToDog = (Dog) mystery;  //?downcast42        backToDog.fetch();  // Now we can call fetch!43        System.out.println("Downcasted: Animal → Dog");44    }45    46    // Method accepts ANY Animal  //?acceptany47    static void feedAnimal(Animal a) {48        System.out.println("Feeding the animal...");49        a.makeSound();  // Works for any animal type50    }51}5253class Animal {54    String name;55    56    Animal(String name) {57        this.name = name;58    }59    60    void makeSound() {61        System.out.println(name + " makes a sound");62    }63}6465class Dog extends Animal {66    Dog(String nameBuddy) {67        super(name);
    All 5 passes — pass 1 is the card above
    passnameadoganimalrexasAnimalmysterybackToDog
    1Buddy⟨Dog C⟩
    2Max⟨Dog D⟩
    3Rex⟨Dog A⟩
    4Rex⟨Dog E⟩⟨Dog E⟩
    5Scout⟨Dog F⟩⟨Dog F⟩
  4. @Override void makeSound()

    pass 1 of 5
    12        System.out.println("Both can make sounds:");13        dog.makeSound();14        animal.makeSound();15        16        System.out.println("\n=== Access Differences ===");17        18        // Dog reference: full access  //?fullaccess19        dog.makeSound();   // OK - inherited20        dog.fetch();       // OK - Dog-specific21        22        // Animal reference: limited access  //?limited23        animal.makeSound();  // OK - defined in Animal24        // animal.fetch();   // ERROR! Animal doesn't know about fetch  //?nofetch25        26        System.out.println("\n=== Why Use Parent Reference? ===");27        28        // Flexibility: accept any animal  //?flexibility29        feedAnimal(new Dog("Rex"));30        feedAnimal(new Cat("Whiskers"));31        32        System.out.println("\n=== Upcasting (Automatic) ===");33        34        Dog rex = new Dog("Rex");35        Animal asAnimal = rex;  //?upcast36        System.out.println("Upcasted: Dog → Animal");37        38        System.out.println("\n=== Downcasting (Manual) ===");39        40        Animal mystery = new Dog("Scout");41        Dog backToDog = (Dog) mystery;  //?downcast42        backToDog.fetch();  // Now we can call fetch!43        System.out.println("Downcasted: Animal → Dog");44    }45    46    // Method accepts ANY Animal  //?acceptany47    static void feedAnimal(Animal a) {48        System.out.println("Feeding the animal...");49        a.makeSound();  // Works for any animal type50    }51}5253class Animal {54    String name;55    56    Animal(String name) {57        this.name = name;58    }59    60    void makeSound() {61        System.out.println(name + " makes a sound");62    }63}6465class Dog extends Animal {66    Dog(String name) {67        super(name);68    }69    70    @Override71    void makeSound() {72        System.out.println(nameBuddy + " barks: Woof!");73    }
    outputBuddy barks: Woof!
    All 5 passes — pass 1 is the card above
    passnamea
    1Buddy
    2Max
    3Buddy
    4Max⟨Dog A⟩
    5Rex⟨Cat B⟩
  5. void fetch()

    pass 1 of 2
    19        dog.makeSound();   // OK - inherited20        dog.fetch();       // OK - Dog-specific21        22        // Animal reference: limited access  //?limited23        animal.makeSound();  // OK - defined in Animal24        // animal.fetch();   // ERROR! Animal doesn't know about fetch  //?nofetch25        26        System.out.println("\n=== Why Use Parent Reference? ===");27        28        // Flexibility: accept any animal  //?flexibility29        feedAnimal(new Dog("Rex"));30        feedAnimal(new Cat("Whiskers"));31        32        System.out.println("\n=== Upcasting (Automatic) ===");33        34        Dog rex = new Dog("Rex");35        Animal asAnimal = rex;  //?upcast36        System.out.println("Upcasted: Dog → Animal");37        38        System.out.println("\n=== Downcasting (Manual) ===");39        40        Animal mystery = new Dog("Scout");41        Dog backToDog = (Dog) mystery;  //?downcast42        backToDog.fetch();  // Now we can call fetch!43        System.out.println("Downcasted: Animal → Dog");44    }45    46    // Method accepts ANY Animal  //?acceptany47    static void feedAnimal(Animal a) {48        System.out.println("Feeding the animal...");49        a.makeSound();  // Works for any animal type50    }51}5253class Animal {54    String name;55    56    Animal(String name) {57        this.name = name;58    }59    60    void makeSound() {61        System.out.println(name + " makes a sound");62    }63}6465class Dog extends Animal {66    Dog(String name) {67        super(name);68    }69    70    @Override71    void makeSound() {72        System.out.println(name + " barks: Woof!");73    }74    75    void fetch() {  //?fetchmethod76        System.out.println(nameBuddy + " fetches the ball!");77    }
    outputBuddy fetches the ball!
  6. static void feedAnimal(Animal a)

    pass 1 of 2
    46// Method accepts ANY Animal  //?acceptany47static void feedAnimal(Animal a⟨Dog A⟩) {48    System.out.println("Feeding the animal...");49    a.makeSound();  // Works for any animal type50}
    outputFeeding the animal...
  7. Cat(String name)

    80class Cat extends Animal {81    Cat(String nameWhiskers) {82        super(name);
  8. static void feedAnimal(Animal a)

    pass 2 of 2
    46// Method accepts ANY Animal  //?acceptany47static void feedAnimal(Animal a⟨Cat B⟩) {48    System.out.println("Feeding the animal...");49    a.makeSound();  // Works for any animal type50}
    outputFeeding the animal...
  9. @Override void makeSound()

    29        feedAnimal(new Dog("Rex"));30        feedAnimal(new Cat("Whiskers"));31        32        System.out.println("\n=== Upcasting (Automatic) ===");33        34        Dog rex = new Dog("Rex");35        Animal asAnimal = rex;  //?upcast36        System.out.println("Upcasted: Dog → Animal");37        38        System.out.println("\n=== Downcasting (Manual) ===");39        40        Animal mystery = new Dog("Scout");41        Dog backToDog = (Dog) mystery;  //?downcast42        backToDog.fetch();  // Now we can call fetch!43        System.out.println("Downcasted: Animal → Dog");44    }45    46    // Method accepts ANY Animal  //?acceptany47    static void feedAnimal(Animal a) {48        System.out.println("Feeding the animal...");49        a.makeSound();  // Works for any animal type50    }51}5253class Animal {54    String name;55    56    Animal(String name) {57        this.name = name;58    }59    60    void makeSound() {61        System.out.println(name + " makes a sound");62    }63}6465class Dog extends Animal {66    Dog(String name) {67        super(name);68    }69    70    @Override71    void makeSound() {72        System.out.println(name + " barks: Woof!");73    }74    75    void fetch() {  //?fetchmethod76        System.out.println(name + " fetches the ball!");77    }78}7980class Cat extends Animal {81    Cat(String name) {82        super(name);83    }84    85    @Override86    void makeSound() {87        System.out.println(nameWhiskers + " meows: Meow!");88    }
    outputWhiskers meows: Meow!
    
    === Upcasting (Automatic) ===
  10. void fetch()

    pass 2 of 2
    41        Dog backToDog = (Dog) mystery;  //?downcast42        backToDog.fetch();  // Now we can call fetch!43        System.out.println("Downcasted: Animal → Dog");44    }45    46    // Method accepts ANY Animal  //?acceptany47    static void feedAnimal(Animal a) {48        System.out.println("Feeding the animal...");49        a.makeSound();  // Works for any animal type50    }51}5253class Animal {54    String name;55    56    Animal(String name) {57        this.name = name;58    }59    60    void makeSound() {61        System.out.println(name + " makes a sound");62    }63}6465class Dog extends Animal {66    Dog(String name) {67        super(name);68    }69    70    @Override71    void makeSound() {72        System.out.println(name + " barks: Woof!");73    }74    75    void fetch() {  //?fetchmethod76        System.out.println(nameScout + " fetches the ball!");77    }
    outputScout fetches the ball!
    Downcasted: Animal → Dog

Method called depends on actual object type, not variable type.

Compile-time polymorphism

Method overloading - same name, different parameters.

MethodOverloading.java
Replay: real traced execution (multi-file project)
// Compile-Time Polymorphism (Method Overloading)

public class MethodOverloading {
    public static void main(String[] args) {
        System.out.println("=== Method Overloading ===\n");

        Calculator calc = new Calculator();

        // Same method name, different parameters
        System.out.println("add(5, 3) = " + calc.add(5, 3));
        System.out.println("add(5, 3, 2) = " + calc.add(5, 3, 2));
        System.out.println("add(5.5, 3.3) = " + calc.add(5.5, 3.3));
        System.out.println("add(\"Hello\", \"World\") = " + calc.add("Hello", "World"));

        System.out.println("\n=== Why 'Compile-Time'? ===");
        System.out.println("""
        Compiler decides which method to call
        based on arguments at compile time.

        add(5, 3)       → calls add(int, int)
        add(5, 3, 2)    → calls add(int, int, int)
        add(5.5, 3.3)   → calls add(double, double)
        add("A", "B")   → calls add(String, String)
        """);

        System.out.println("=== Overloading Rules ===");

        Printer printer = new Printer();

        // Different number of parameters
        printer.print("Hello");
        printer.print("Hello", 3);

        // Different parameter types
        printer.print(42);
        printer.print(3.14);

        // Different parameter order
        printer.display("Name", 1);
        printer.display(1, "Name");

        System.out.println("\n=== Return Type Doesn't Count ===");
        System.out.println("""
        // INVALID overloading:
        int getValue() { return 1; }
        double getValue() { return 1.0; }  // ERROR!

        Return type alone cannot distinguish methods.
        Parameters must be different.
        """);
    }
}

class Calculator {
    // Overloaded add methods

    int add(int a, int b) {
        return a + b;
    }

    int add(int a, int b, int c) {
        return a + b + c;
    }

    double add(double a, double b) {
        return a + b;
    }

    String add(String a, String b) {
        return a + " " + b;
    }
}

class Printer {
    void print(String message) {
        System.out.println("String: " + message);
    }

    void print(String message, int times) {
        for (int i = 0; i < times; i++) {
            System.out.println(message);
        }
    }

    void print(int number) {
        System.out.println("Integer: " + number);
    }

    void print(double number) {
        System.out.println("Double: " + number);
    }

    void display(String label, int value) {
        System.out.println(label + " = " + value);
    }

    void display(int value, String label) {
        System.out.println(value + ": " + label);
    }
}

  1. calc ← ⟨Calculator A⟩

    3public class MethodOverloading {4    public static void main(String[] args) {5        System.out.println("=== Method Overloading ===\n");6        7        Calculator calc→ ⟨Calculator A⟩ = new Calculator();8        9        // Same method name, different parameters  //?samemethod10        System.out.println("add(5, 3) = " + calc.add(5, 3));           //?add2int11        System.out.println("add(5, 3, 2) = " + calc.add(5, 3, 2));     //?add3int
    output=== Method Overloading ===
  2. int add(int a, int b)

    57int add(int a5, int b3) {  //?addint58    return a5 + b3;59}
  3. System.out.println("add(5, 3) = " + calc.add(5, 3)); //?add2…

    9// Same method name, different parameters  //?samemethod10System.out.println("add(5, 3) = " + calc.add(5, 3));           //?add2int11System.out.println("add(5, 3, 2) = " + calc.add(5, 3, 2));     //?add3int12System.out.println("add(5.5, 3.3) = " + calc.add(5.5, 3.3));   //?add2double
    outputadd(5, 3) = 8
  4. int add(int a, int b, int c)

    61int add(int a5, int b3, int c2) {  //?addthree62    return a5 + b3 + c2;63}
  5. System.out.println("add(5, 3, 2) = " + calc.add(5, 3, 2)); //?add3…

    10System.out.println("add(5, 3) = " + calc.add(5, 3));           //?add2int11System.out.println("add(5, 3, 2) = " + calc.add(5, 3, 2));     //?add3int12System.out.println("add(5.5, 3.3) = " + calc.add(5.5, 3.3));   //?add2double13System.out.println("add(\"Hello\", \"World\") = " + calc.add("Hello", "World"));  //?addstring
    outputadd(5, 3, 2) = 10
  6. double add(double a, double b)

    65double add(double a5.5, double b3.3) {  //?adddouble66    return a5.5 + b3.3;67}
  7. System.out.println("add(5.5, 3.3) = " + calc.add(5.5, 3.3)); //?add2…

    11System.out.println("add(5, 3, 2) = " + calc.add(5, 3, 2));     //?add3int12System.out.println("add(5.5, 3.3) = " + calc.add(5.5, 3.3));   //?add2double13System.out.println("add(\"Hello\", \"World\") = " + calc.add("Hello", "World"));  //?addstring
    outputadd(5.5, 3.3) = 8.8
  8. String add(String a, String b)

    69String add(String aHello, String bWorld) {  //?addstrings70    return aHello + " " + bWorld;71}
  9. printer ← ⟨Printer B⟩

    12System.out.println("add(5.5, 3.3) = " + calc.add(5.5, 3.3));   //?add2double13System.out.println("add(\"Hello\", \"World\") = " + calc.add("Hello", "World"));  //?addstring1415System.out.println("\n=== Why 'Compile-Time'? ===");16System.out.println("""17Compiler decides which method to call18based on arguments at compile time.1920add(5, 3)       → calls add(int, int)21add(5, 3, 2)    → calls add(int, int, int)22add(5.5, 3.3)   → calls add(double, double)23add("A", "B")   → calls add(String, String)24""");2526System.out.println("=== Overloading Rules ===");2728Printer printer→ ⟨Printer B⟩ = new Printer();2930// Different number of parameters  //?diffcount31printer.print("Hello");32printer.print("Hello", 3);
    outputadd("Hello", "World") = Hello World
    
    === Why 'Compile-Time'? ===
    Compiler decides which method to call
    based on arguments at compile time.
    
    add(5, 3)       → calls add(int, int)
    add(5, 3, 2)    → calls add(int, int, int)
    add(5.5, 3.3)   → calls add(double, double)
    add("A", "B")   → calls add(String, String)
    === Overloading Rules ===
  10. void print(String message)

    30        // Different number of parameters  //?diffcount31        printer.print("Hello");32        printer.print("Hello", 3);33        34        // Different parameter types  //?difftypes35        printer.print(42);36        printer.print(3.14);37        38        // Different parameter order  //?difforder39        printer.display("Name", 1);40        printer.display(1, "Name");41        42        System.out.println("\n=== Return Type Doesn't Count ===");43        System.out.println("""44        // INVALID overloading:45        int getValue() { return 1; }46        double getValue() { return 1.0; }  // ERROR!47        48        Return type alone cannot distinguish methods.49        Parameters must be different.50        """);51    }52}5354class Calculator {55    // Overloaded add methods  //?overloaded56    57    int add(int a, int b) {  //?addint58        return a + b;59    }60    61    int add(int a, int b, int c) {  //?addthree62        return a + b + c;63    }64    65    double add(double a, double b) {  //?adddouble66        return a + b;67    }68    69    String add(String a, String b) {  //?addstrings70        return a + " " + b;71    }72}7374class Printer {75    void print(String messageHello) {  //?printstr76        System.out.println("String: " + messageHello);77    }
    outputString: Hello
  11. void print(String message, int times)

    79void print(String messageHello, int times3) {  //?printtimes80    for (int i = 0; i < times; i++) {
  12. for (int i = 0; i < times; i++)

    pass 1 of 3
    79void print(String message, int times) {  //?printtimes80    for (int i0 = 0; i < times3; i++) {81        System.out.println(messageHello);82    }
    outputHello
    All 3 passes — pass 1 is the card above
    passinumberlabelvalue
    10
    21
    3242Name1
  13. void print(int number)

    34        // Different parameter types  //?difftypes35        printer.print(42);36        printer.print(3.14);37        38        // Different parameter order  //?difforder39        printer.display("Name", 1);40        printer.display(1, "Name");41        42        System.out.println("\n=== Return Type Doesn't Count ===");43        System.out.println("""44        // INVALID overloading:45        int getValue() { return 1; }46        double getValue() { return 1.0; }  // ERROR!47        48        Return type alone cannot distinguish methods.49        Parameters must be different.50        """);51    }52}5354class Calculator {55    // Overloaded add methods  //?overloaded56    57    int add(int a, int b) {  //?addint58        return a + b;59    }60    61    int add(int a, int b, int c) {  //?addthree62        return a + b + c;63    }64    65    double add(double a, double b) {  //?adddouble66        return a + b;67    }68    69    String add(String a, String b) {  //?addstrings70        return a + " " + b;71    }72}7374class Printer {75    void print(String message) {  //?printstr76        System.out.println("String: " + message);77    }78    79    void print(String message, int times) {  //?printtimes80        for (int i = 0; i < times; i++) {81            System.out.println(message);82        }83    }84    85    void print(int number42) {  //?printint86        System.out.println("Integer: " + number42);87    }
    outputInteger: 42
  14. void print(double number)

    35        printer.print(42);36        printer.print(3.14);37        38        // Different parameter order  //?difforder39        printer.display("Name", 1);40        printer.display(1, "Name");41        42        System.out.println("\n=== Return Type Doesn't Count ===");43        System.out.println("""44        // INVALID overloading:45        int getValue() { return 1; }46        double getValue() { return 1.0; }  // ERROR!47        48        Return type alone cannot distinguish methods.49        Parameters must be different.50        """);51    }52}5354class Calculator {55    // Overloaded add methods  //?overloaded56    57    int add(int a, int b) {  //?addint58        return a + b;59    }60    61    int add(int a, int b, int c) {  //?addthree62        return a + b + c;63    }64    65    double add(double a, double b) {  //?adddouble66        return a + b;67    }68    69    String add(String a, String b) {  //?addstrings70        return a + " " + b;71    }72}7374class Printer {75    void print(String message) {  //?printstr76        System.out.println("String: " + message);77    }78    79    void print(String message, int times) {  //?printtimes80        for (int i = 0; i < times; i++) {81            System.out.println(message);82        }83    }84    85    void print(int number) {  //?printint86        System.out.println("Integer: " + number);87    }88    89    void print(double number3.14) {  //?printdouble90        System.out.println("Double: " + number3.14);91    }
    outputDouble: 3.14
  15. void display(String label, int value)

    38        // Different parameter order  //?difforder39        printer.display("Name", 1);40        printer.display(1, "Name");41        42        System.out.println("\n=== Return Type Doesn't Count ===");43        System.out.println("""44        // INVALID overloading:45        int getValue() { return 1; }46        double getValue() { return 1.0; }  // ERROR!47        48        Return type alone cannot distinguish methods.49        Parameters must be different.50        """);51    }52}5354class Calculator {55    // Overloaded add methods  //?overloaded56    57    int add(int a, int b) {  //?addint58        return a + b;59    }60    61    int add(int a, int b, int c) {  //?addthree62        return a + b + c;63    }64    65    double add(double a, double b) {  //?adddouble66        return a + b;67    }68    69    String add(String a, String b) {  //?addstrings70        return a + " " + b;71    }72}7374class Printer {75    void print(String message) {  //?printstr76        System.out.println("String: " + message);77    }78    79    void print(String message, int times) {  //?printtimes80        for (int i = 0; i < times; i++) {81            System.out.println(message);82        }83    }84    85    void print(int number) {  //?printint86        System.out.println("Integer: " + number);87    }88    89    void print(double number) {  //?printdouble90        System.out.println("Double: " + number);91    }92    93    void display(String labelName, int value1) {  //?displaysi94        System.out.println(labelName + " = " + value1);95    }
    outputName = 1
  16. void display(int value, String label)

    39        printer.display("Name", 1);40        printer.display(1, "Name");41        42        System.out.println("\n=== Return Type Doesn't Count ===");43        System.out.println("""44        // INVALID overloading:45        int getValue() { return 1; }46        double getValue() { return 1.0; }  // ERROR!47        48        Return type alone cannot distinguish methods.49        Parameters must be different.50        """);51    }52}5354class Calculator {55    // Overloaded add methods  //?overloaded56    57    int add(int a, int b) {  //?addint58        return a + b;59    }60    61    int add(int a, int b, int c) {  //?addthree62        return a + b + c;63    }64    65    double add(double a, double b) {  //?adddouble66        return a + b;67    }68    69    String add(String a, String b) {  //?addstrings70        return a + " " + b;71    }72}7374class Printer {75    void print(String message) {  //?printstr76        System.out.println("String: " + message);77    }78    79    void print(String message, int times) {  //?printtimes80        for (int i = 0; i < times; i++) {81            System.out.println(message);82        }83    }84    85    void print(int number) {  //?printint86        System.out.println("Integer: " + number);87    }88    89    void print(double number) {  //?printdouble90        System.out.println("Double: " + number);91    }92    93    void display(String label, int value) {  //?displaysi94        System.out.println(label + " = " + value);95    }96    97    void display(int value1, String labelName) {  //?displayis98        System.out.println(value1 + ": " + labelName);99    }
    output1: Name
    
    === Return Type Doesn't Count ===
    // INVALID overloading:
    int getValue() { return 1; }
    double getValue() { return 1.0; }  // ERROR!
    
    Return type alone cannot distinguish methods.
    Parameters must be different.

Compiler chooses method based on argument types at compile time.

overloading Same method name, different parameters. Resolved at compile time.

Arrays of polymorphic objects

Store different subtypes in one array.

ArrayPolymorphism.java
Replay: real traced execution (multi-file project)
// Arrays and Collections with Polymorphism

public class ArrayPolymorphism {
    public static void main(String[] args) {
        System.out.println("=== Polymorphic Array ===\n");

        // Array of parent type holding different child objects
        Shape[] shapes = new Shape[4];
        shapes[0] = new Circle(5.0);
        shapes[1] = new Rectangle(4.0, 6.0);
        shapes[2] = new Triangle(3.0, 4.0);
        shapes[3] = new Circle(2.5);

        // Process all shapes uniformly
        System.out.println("Drawing all shapes:");
        for (Shape shape : shapes) {
            shape.draw();
        }

        System.out.println("\n=== Calculating Total Area ===");

        double totalArea = 0;
        for (Shape shape : shapes) {
            double area = shape.getArea();
            System.out.println("Area: " + String.format("%.2f", area));
            totalArea += area;
        }
        System.out.println("Total: " + String.format("%.2f", totalArea));

        System.out.println("\n=== Array Initialization Shorthand ===");

        Shape[] moreShapes = {
            new Circle(1.0),
            new Rectangle(2.0, 3.0),
            new Triangle(4.0, 5.0)
        };

        for (Shape s : moreShapes) {
            s.draw();
        }

        System.out.println("\n=== Pass Array to Method ===");

        printShapeInfo(shapes);
    }

    // Method accepts array of Shape
    static void printShapeInfo(Shape[] shapes) {
        System.out.println("Processing " + shapes.length + " shapes:");
        for (int i = 0; i < shapes.length; i++) {
            System.out.println((i + 1) + ". " + shapes[i].getName() +
                             " - Area: " + String.format("%.2f", shapes[i].getArea()));
        }
    }
}

class Shape {
    String getName() {
        return "Shape";
    }

    void draw() {
        System.out.println("Drawing a shape");
    }

    double getArea() {
        return 0;
    }
}

class Circle extends Shape {
    double radius;

    Circle(double radius) {
        this.radius = radius;
    }

    @Override
    String getName() {
        return "Circle (r=" + radius + ")";
    }

    @Override
    void draw() {
        System.out.println("Drawing circle with radius " + radius);
    }

    @Override
    double getArea() {
        return Math.PI * radius * radius;
    }
}

class Rectangle extends Shape {
    double width, height;

    Rectangle(double width, double height) {
        this.width = width;
        this.height = height;
    }

    @Override
    String getName() {
        return "Rectangle (" + width + "x" + height + ")";
    }

    @Override
    void draw() {
        System.out.println("Drawing rectangle " + width + " x " + height);
    }

    @Override
    double getArea() {
        return width * height;
    }
}

class Triangle extends Shape {
    double base, height;

    Triangle(double base, double height) {
        this.base = base;
        this.height = height;
    }

    @Override
    String getName() {
        return "Triangle (b=" + base + ", h=" + height + ")";
    }

    @Override
    void draw() {
        System.out.println("Drawing triangle with base " + base + " and height " + height);
    }

    @Override
    double getArea() {
        return 0.5 * base * height;
    }
}

  1. public static void main(String[] args)

    3public class ArrayPolymorphism {4    public static void main(String[] args) {5        System.out.println("=== Polymorphic Array ===\n");6        7        // Array of parent type holding different child objects  //?polyarray8        Shape[] shapes = new Shape[4];9        shapes[0]null = new Circle(5.0);       //?addcircle10        shapes[1] = new Rectangle(4.0, 6.0);
    output=== Polymorphic Array ===
  2. this.radius ← 5.0, shapes[0] ← ⟨Circle A⟩

    pass 1 of 3
    8        Shape[] shapes = new Shape[4];9        shapes[0]→ ⟨Circle A⟩ = new Circle(5.0);       //?addcircle10        shapes[1]null = new Rectangle(4.0, 6.0);11        shapes[2] = new Triangle(3.0, 4.0);12        shapes[3] = new Circle(2.5);13        14        // Process all shapes uniformly  //?uniform15        System.out.println("Drawing all shapes:");16        for (Shape shape : shapes) {17            shape.draw();  //?drawcall18        }19        20        System.out.println("\n=== Calculating Total Area ===");21        22        double totalArea = 0;23        for (Shape shape : shapes) {24            double area = shape.getArea();  //?areacall25            System.out.println("Area: " + String.format("%.2f", area));26            totalArea += area;27        }28        System.out.println("Total: " + String.format("%.2f", totalArea));29        30        System.out.println("\n=== Array Initialization Shorthand ===");31        32        Shape[] moreShapes = {  //?shorthand33            new Circle(1.0),34            new Rectangle(2.0, 3.0),35            new Triangle(4.0, 5.0)36        };37        38        for (Shape s : moreShapes) {39            s.draw();40        }41        42        System.out.println("\n=== Pass Array to Method ===");43        44        printShapeInfo(shapes);  //?passarray45    }46    47    // Method accepts array of Shape  //?arraymethod48    static void printShapeInfo(Shape[] shapes) {49        System.out.println("Processing " + shapes.length + " shapes:");50        for (int i = 0; i < shapes.length; i++) {51            System.out.println((i + 1) + ". " + shapes[i].getName() + 52                             " - Area: " + String.format("%.2f", shapes[i].getArea()));53        }54    }55}5657class Shape {58    String getName() {59        return "Shape";60    }61    62    void draw() {63        System.out.println("Drawing a shape");64    }65    66    double getArea() {67        return 0;68    }69}7071class Circle extends Shape {72    double radius;73    74    Circle(double radius5.0) {75        this.radius→ 5.0 = radius5.0;76    }
    All 3 passes — pass 1 is the card above
    passradiuswidthheightshapes[2]baseshapes.lengththis.radiusshapes[0]this.widththis.heightshapes[1]this.baseshapes[3]
    15.04.06.0null3.05.0null ⟨Circle A⟩4.06.0null ⟨Rectangle B⟩3.0null
    22.54.06.03.02.5null ⟨Circle C⟩
    31.02.03.04.041.02.03.04.0
  3. this.width ← 4.0, this.height ← 6.0, shapes[1] ← ⟨Rectangle B⟩

    pass 1 of 2
    9        shapes[0] = new Circle(5.0);       //?addcircle10        shapes[1]→ ⟨Rectangle B⟩ = new Rectangle(4.0, 6.0);11        shapes[2]null = new Triangle(3.0, 4.0);12        shapes[3] = new Circle(2.5);13        14        // Process all shapes uniformly  //?uniform15        System.out.println("Drawing all shapes:");16        for (Shape shape : shapes) {17            shape.draw();  //?drawcall18        }19        20        System.out.println("\n=== Calculating Total Area ===");21        22        double totalArea = 0;23        for (Shape shape : shapes) {24            double area = shape.getArea();  //?areacall25            System.out.println("Area: " + String.format("%.2f", area));26            totalArea += area;27        }28        System.out.println("Total: " + String.format("%.2f", totalArea));29        30        System.out.println("\n=== Array Initialization Shorthand ===");31        32        Shape[] moreShapes = {  //?shorthand33            new Circle(1.0),34            new Rectangle(2.0, 3.0),35            new Triangle(4.0, 5.0)36        };37        38        for (Shape s : moreShapes) {39            s.draw();40        }41        42        System.out.println("\n=== Pass Array to Method ===");43        44        printShapeInfo(shapes);  //?passarray45    }46    47    // Method accepts array of Shape  //?arraymethod48    static void printShapeInfo(Shape[] shapes) {49        System.out.println("Processing " + shapes.length + " shapes:");50        for (int i = 0; i < shapes.length; i++) {51            System.out.println((i + 1) + ". " + shapes[i].getName() + 52                             " - Area: " + String.format("%.2f", shapes[i].getArea()));53        }54    }55}5657class Shape {58    String getName() {59        return "Shape";60    }61    62    void draw() {63        System.out.println("Drawing a shape");64    }65    66    double getArea() {67        return 0;68    }69}7071class Circle extends Shape {72    double radius;73    74    Circle(double radius) {75        this.radius = radius;76    }77    78    @Override79    String getName() {80        return "Circle (r=" + radius + ")";81    }82    83    @Override84    void draw() {  //?circledraw85        System.out.println("Drawing circle with radius " + radius);86    }87    88    @Override89    double getArea() {  //?circlearea90        return Math.PI * radius * radius;91    }92}9394class Rectangle extends Shape {95    double width, height;96    97    Rectangle(double width4.0, double height6.0) {98        this.width→ 4.0 = width4.0;99        this.height→ 6.0 = height6.0;100    }
  4. this.base ← 3.0, this.height ← 4.0, shapes[2] ← ⟨Triangle D⟩

    pass 1 of 2
    10        shapes[1] = new Rectangle(4.0, 6.0);11        shapes[2]→ ⟨Triangle D⟩ = new Triangle(3.0, 4.0);12        shapes[3]null = new Circle(2.5);13        14        // Process all shapes uniformly  //?uniform15        System.out.println("Drawing all shapes:");16        for (Shape shape : shapes) {17            shape.draw();  //?drawcall18        }19        20        System.out.println("\n=== Calculating Total Area ===");21        22        double totalArea = 0;23        for (Shape shape : shapes) {24            double area = shape.getArea();  //?areacall25            System.out.println("Area: " + String.format("%.2f", area));26            totalArea += area;27        }28        System.out.println("Total: " + String.format("%.2f", totalArea));29        30        System.out.println("\n=== Array Initialization Shorthand ===");31        32        Shape[] moreShapes = {  //?shorthand33            new Circle(1.0),34            new Rectangle(2.0, 3.0),35            new Triangle(4.0, 5.0)36        };37        38        for (Shape s : moreShapes) {39            s.draw();40        }41        42        System.out.println("\n=== Pass Array to Method ===");43        44        printShapeInfo(shapes);  //?passarray45    }46    47    // Method accepts array of Shape  //?arraymethod48    static void printShapeInfo(Shape[] shapes) {49        System.out.println("Processing " + shapes.length + " shapes:");50        for (int i = 0; i < shapes.length; i++) {51            System.out.println((i + 1) + ". " + shapes[i].getName() + 52                             " - Area: " + String.format("%.2f", shapes[i].getArea()));53        }54    }55}5657class Shape {58    String getName() {59        return "Shape";60    }61    62    void draw() {63        System.out.println("Drawing a shape");64    }65    66    double getArea() {67        return 0;68    }69}7071class Circle extends Shape {72    double radius;73    74    Circle(double radius) {75        this.radius = radius;76    }77    78    @Override79    String getName() {80        return "Circle (r=" + radius + ")";81    }82    83    @Override84    void draw() {  //?circledraw85        System.out.println("Drawing circle with radius " + radius);86    }87    88    @Override89    double getArea() {  //?circlearea90        return Math.PI * radius * radius;91    }92}9394class Rectangle extends Shape {95    double width, height;96    97    Rectangle(double width, double height) {98        this.width = width;99        this.height = height;100    }101    102    @Override103    String getName() {104        return "Rectangle (" + width + "x" + height + ")";105    }106    107    @Override108    void draw() {109        System.out.println("Drawing rectangle " + width + " x " + height);110    }111    112    @Override113    double getArea() {114        return width * height;115    }116}117118class Triangle extends Shape {119    double base, height;120    121    Triangle(double base3.0, double height4.0) {122        this.base→ 3.0 = base3.0;123        this.height→ 4.0 = height4.0;124    }
  5. for (Shape shape : shapes)

    pass 1 of 4
    15System.out.println("Drawing all shapes:");16for (Shape shape⟨Circle A⟩ : shapes) {17    shape.draw();  //?drawcall18}
    All 4 passes — pass 1 is the card above
    passshapewidthheightbase
    1⟨Circle A⟩
    2⟨Rectangle B⟩4.06.0
    3⟨Triangle D⟩4.03.0
    4⟨Circle C⟩
  6. @Override void draw()

    pass 1 of 3
    16        for (Shape shape : shapes) {17            shape.draw();  //?drawcall18        }19        20        System.out.println("\n=== Calculating Total Area ===");21        22        double totalArea = 0;23        for (Shape shape : shapes) {24            double area = shape.getArea();  //?areacall25            System.out.println("Area: " + String.format("%.2f", area));26            totalArea += area;27        }28        System.out.println("Total: " + String.format("%.2f", totalArea));29        30        System.out.println("\n=== Array Initialization Shorthand ===");31        32        Shape[] moreShapes = {  //?shorthand33            new Circle(1.0),34            new Rectangle(2.0, 3.0),35            new Triangle(4.0, 5.0)36        };37        38        for (Shape s : moreShapes) {39            s.draw();40        }41        42        System.out.println("\n=== Pass Array to Method ===");43        44        printShapeInfo(shapes);  //?passarray45    }46    47    // Method accepts array of Shape  //?arraymethod48    static void printShapeInfo(Shape[] shapes) {49        System.out.println("Processing " + shapes.length + " shapes:");50        for (int i = 0; i < shapes.length; i++) {51            System.out.println((i + 1) + ". " + shapes[i].getName() + 52                             " - Area: " + String.format("%.2f", shapes[i].getArea()));53        }54    }55}5657class Shape {58    String getName() {59        return "Shape";60    }61    62    void draw() {63        System.out.println("Drawing a shape");64    }65    66    double getArea() {67        return 0;68    }69}7071class Circle extends Shape {72    double radius;73    74    Circle(double radius) {75        this.radius = radius;76    }77    78    @Override79    String getName() {80        return "Circle (r=" + radius + ")";81    }82    83    @Override84    void draw() {  //?circledraw85        System.out.println("Drawing circle with radius " + radius5.0);86    }
    outputDrawing circle with radius 5.0
    All 3 passes — pass 1 is the card above
    passradiuswidthheightbaseshapes.lengthtotalArea
    15.04.06.03.0
    22.50.0
    31.02.03.04.04
  7. @Override void draw()

    pass 1 of 2
    16        for (Shape shape : shapes) {17            shape.draw();  //?drawcall18        }19        20        System.out.println("\n=== Calculating Total Area ===");21        22        double totalArea = 0;23        for (Shape shape : shapes) {24            double area = shape.getArea();  //?areacall25            System.out.println("Area: " + String.format("%.2f", area));26            totalArea += area;27        }28        System.out.println("Total: " + String.format("%.2f", totalArea));29        30        System.out.println("\n=== Array Initialization Shorthand ===");31        32        Shape[] moreShapes = {  //?shorthand33            new Circle(1.0),34            new Rectangle(2.0, 3.0),35            new Triangle(4.0, 5.0)36        };37        38        for (Shape s : moreShapes) {39            s.draw();40        }41        42        System.out.println("\n=== Pass Array to Method ===");43        44        printShapeInfo(shapes);  //?passarray45    }46    47    // Method accepts array of Shape  //?arraymethod48    static void printShapeInfo(Shape[] shapes) {49        System.out.println("Processing " + shapes.length + " shapes:");50        for (int i = 0; i < shapes.length; i++) {51            System.out.println((i + 1) + ". " + shapes[i].getName() + 52                             " - Area: " + String.format("%.2f", shapes[i].getArea()));53        }54    }55}5657class Shape {58    String getName() {59        return "Shape";60    }61    62    void draw() {63        System.out.println("Drawing a shape");64    }65    66    double getArea() {67        return 0;68    }69}7071class Circle extends Shape {72    double radius;73    74    Circle(double radius) {75        this.radius = radius;76    }77    78    @Override79    String getName() {80        return "Circle (r=" + radius + ")";81    }82    83    @Override84    void draw() {  //?circledraw85        System.out.println("Drawing circle with radius " + radius);86    }87    88    @Override89    double getArea() {  //?circlearea90        return Math.PI * radius * radius;91    }92}9394class Rectangle extends Shape {95    double width, height;96    97    Rectangle(double width, double height) {98        this.width = width;99        this.height = height;100    }101    102    @Override103    String getName() {104        return "Rectangle (" + width + "x" + height + ")";105    }106    107    @Override108    void draw() {109        System.out.println("Drawing rectangle " + width4.0 + " x " + height6.0);110    }
    outputDrawing rectangle 4.0 x 6.0
  8. @Override void draw()

    pass 1 of 2
    16        for (Shape shape : shapes) {17            shape.draw();  //?drawcall18        }19        20        System.out.println("\n=== Calculating Total Area ===");21        22        double totalArea = 0;23        for (Shape shape : shapes) {24            double area = shape.getArea();  //?areacall25            System.out.println("Area: " + String.format("%.2f", area));26            totalArea += area;27        }28        System.out.println("Total: " + String.format("%.2f", totalArea));29        30        System.out.println("\n=== Array Initialization Shorthand ===");31        32        Shape[] moreShapes = {  //?shorthand33            new Circle(1.0),34            new Rectangle(2.0, 3.0),35            new Triangle(4.0, 5.0)36        };37        38        for (Shape s : moreShapes) {39            s.draw();40        }41        42        System.out.println("\n=== Pass Array to Method ===");43        44        printShapeInfo(shapes);  //?passarray45    }46    47    // Method accepts array of Shape  //?arraymethod48    static void printShapeInfo(Shape[] shapes) {49        System.out.println("Processing " + shapes.length + " shapes:");50        for (int i = 0; i < shapes.length; i++) {51            System.out.println((i + 1) + ". " + shapes[i].getName() + 52                             " - Area: " + String.format("%.2f", shapes[i].getArea()));53        }54    }55}5657class Shape {58    String getName() {59        return "Shape";60    }61    62    void draw() {63        System.out.println("Drawing a shape");64    }65    66    double getArea() {67        return 0;68    }69}7071class Circle extends Shape {72    double radius;73    74    Circle(double radius) {75        this.radius = radius;76    }77    78    @Override79    String getName() {80        return "Circle (r=" + radius + ")";81    }82    83    @Override84    void draw() {  //?circledraw85        System.out.println("Drawing circle with radius " + radius);86    }87    88    @Override89    double getArea() {  //?circlearea90        return Math.PI * radius * radius;91    }92}9394class Rectangle extends Shape {95    double width, height;96    97    Rectangle(double width, double height) {98        this.width = width;99        this.height = height;100    }101    102    @Override103    String getName() {104        return "Rectangle (" + width + "x" + height + ")";105    }106    107    @Override108    void draw() {109        System.out.println("Drawing rectangle " + width + " x " + height);110    }111    112    @Override113    double getArea() {114        return width * height;115    }116}117118class Triangle extends Shape {119    double base, height;120    121    Triangle(double base, double height) {122        this.base = base;123        this.height = height;124    }125    126    @Override127    String getName() {128        return "Triangle (b=" + base + ", h=" + height + ")";129    }130    131    @Override132    void draw() {133        System.out.println("Drawing triangle with base " + base3.0 + " and height " + height4.0);134    }
    outputDrawing triangle with base 3.0 and height 4.0
  9. for (Shape shape : shapes)

    pass 1 of 4
    22double totalArea = 0;23for (Shape shape⟨Circle A⟩ : shapes) {24    double area = shape.getArea();  //?areacall25    System.out.println("Area: " + String.format("%.2f", area));
    All 4 passes — pass 1 is the card above
    passshapewidthheightbase
    1⟨Circle A⟩
    2⟨Rectangle B⟩4.06.0
    3⟨Triangle D⟩4.03.0
    4⟨Circle C⟩
  10. @Override double getArea()

    pass 1 of 4
    88@Override89double getArea() {  //?circlearea90    return Math.PI * radius5.0 * radius;91}
    All 4 passes — pass 1 is the card above
    passradius
    15.0
    22.5
    35.0
    42.5
  11. area ← 78.53981633974483, totalArea ← 78.53981633974483

    23for (Shape shape : shapes) {24    double area→ 78.53981633974483 = shape.getArea();  //?areacall25    System.out.println("Area: " + String.format("%.2f", area78.53981633974483));26    totalArea→ 78.53981633974483 += area78.53981633974483;27}
    outputArea: 78.54
  12. @Override double getArea()

    pass 1 of 2
    112@Override113double getArea() {114    return width4.0 * height6.0;115}
  13. area ← 24.0, totalArea ← 102.53981633974483

    23for (Shape shape : shapes) {24    double area→ 24.0 = shape.getArea();  //?areacall25    System.out.println("Area: " + String.format("%.2f", area24.0));26    totalArea→ 102.53981633974483 += area24.0;27}
    outputArea: 24.00
  14. @Override double getArea()

    pass 1 of 2
    136@Override137double getArea() {138    return 0.5 * base3.0 * height4.0;139}
  15. area ← 6.0, totalArea ← 108.53981633974483

    23for (Shape shape : shapes) {24    double area→ 6.0 = shape.getArea();  //?areacall25    System.out.println("Area: " + String.format("%.2f", area6.0));26    totalArea→ 108.53981633974483 += area6.0;27}
    outputArea: 6.00
  16. area ← 19.634954084936208, totalArea ← 128.17477042468104

    23for (Shape shape : shapes) {24    double area→ 19.634954084936208 = shape.getArea();  //?areacall25    System.out.println("Area: " + String.format("%.2f", area19.634954084936208));26    totalArea→ 128.17477042468104 += area19.634954084936208;27}28System.out.println("Total: " + String.format("%.2f", totalArea128.17477042468104));2930System.out.println("\n=== Array Initialization Shorthand ===");3132Shape[] moreShapes = {  //?shorthand33    new Circle(1.0),34    new Rectangle(2.0, 3.0),35    new Triangle(4.0, 5.0)36};
    outputArea: 19.63
    Total: 128.17
    
    === Array Initialization Shorthand ===
  17. this.width ← 2.0, this.height ← 3.0

    pass 2 of 2
    97Rectangle(double width2.0, double height3.0) {98    this.width→ 2.0 = width2.0;99    this.height→ 3.0 = height3.0;100}
  18. this.base ← 4.0, this.height ← 5.0

    pass 2 of 2
    32        Shape[] moreShapes = {  //?shorthand33            new Circle(1.0),34            new Rectangle(2.0, 3.0),35            new Triangle(4.0, 5.0)36        };37        38        for (Shape s : moreShapes) {39            s.draw();40        }41        42        System.out.println("\n=== Pass Array to Method ===");43        44        printShapeInfo(shapes);  //?passarray45    }46    47    // Method accepts array of Shape  //?arraymethod48    static void printShapeInfo(Shape[] shapes) {49        System.out.println("Processing " + shapes.length + " shapes:");50        for (int i = 0; i < shapes.length; i++) {51            System.out.println((i + 1) + ". " + shapes[i].getName() + 52                             " - Area: " + String.format("%.2f", shapes[i].getArea()));53        }54    }55}5657class Shape {58    String getName() {59        return "Shape";60    }61    62    void draw() {63        System.out.println("Drawing a shape");64    }65    66    double getArea() {67        return 0;68    }69}7071class Circle extends Shape {72    double radius;73    74    Circle(double radius) {75        this.radius = radius;76    }77    78    @Override79    String getName() {80        return "Circle (r=" + radius + ")";81    }82    83    @Override84    void draw() {  //?circledraw85        System.out.println("Drawing circle with radius " + radius);86    }87    88    @Override89    double getArea() {  //?circlearea90        return Math.PI * radius * radius;91    }92}9394class Rectangle extends Shape {95    double width, height;96    97    Rectangle(double width, double height) {98        this.width = width;99        this.height = height;100    }101    102    @Override103    String getName() {104        return "Rectangle (" + width + "x" + height + ")";105    }106    107    @Override108    void draw() {109        System.out.println("Drawing rectangle " + width + " x " + height);110    }111    112    @Override113    double getArea() {114        return width * height;115    }116}117118class Triangle extends Shape {119    double base, height;120    121    Triangle(double base4.0, double height5.0) {122        this.base→ 4.0 = base4.0;123        this.height→ 5.0 = height5.0;124    }
  19. for (Shape s : moreShapes)

    pass 1 of 3
    38for (Shape s⟨Circle E⟩ : moreShapes) {39    s.draw();40}
    All 3 passes — pass 1 is the card above
    passswidthheightbaseshapes.lengthradius
    1⟨Circle E⟩
    2⟨Rectangle F⟩2.03.0
    3⟨Triangle G⟩5.04.045.0
  20. @Override void draw()

    pass 2 of 2
    38        for (Shape s : moreShapes) {39            s.draw();40        }41        42        System.out.println("\n=== Pass Array to Method ===");43        44        printShapeInfo(shapes);  //?passarray45    }46    47    // Method accepts array of Shape  //?arraymethod48    static void printShapeInfo(Shape[] shapes) {49        System.out.println("Processing " + shapes.length + " shapes:");50        for (int i = 0; i < shapes.length; i++) {51            System.out.println((i + 1) + ". " + shapes[i].getName() + 52                             " - Area: " + String.format("%.2f", shapes[i].getArea()));53        }54    }55}5657class Shape {58    String getName() {59        return "Shape";60    }61    62    void draw() {63        System.out.println("Drawing a shape");64    }65    66    double getArea() {67        return 0;68    }69}7071class Circle extends Shape {72    double radius;73    74    Circle(double radius) {75        this.radius = radius;76    }77    78    @Override79    String getName() {80        return "Circle (r=" + radius + ")";81    }82    83    @Override84    void draw() {  //?circledraw85        System.out.println("Drawing circle with radius " + radius);86    }87    88    @Override89    double getArea() {  //?circlearea90        return Math.PI * radius * radius;91    }92}9394class Rectangle extends Shape {95    double width, height;96    97    Rectangle(double width, double height) {98        this.width = width;99        this.height = height;100    }101    102    @Override103    String getName() {104        return "Rectangle (" + width + "x" + height + ")";105    }106    107    @Override108    void draw() {109        System.out.println("Drawing rectangle " + width2.0 + " x " + height3.0);110    }
    outputDrawing rectangle 2.0 x 3.0
  21. @Override void draw()

    pass 2 of 2
    38        for (Shape s : moreShapes) {39            s.draw();40        }41        42        System.out.println("\n=== Pass Array to Method ===");43        44        printShapeInfo(shapes);  //?passarray45    }46    47    // Method accepts array of Shape  //?arraymethod48    static void printShapeInfo(Shape[] shapes) {49        System.out.println("Processing " + shapes.length + " shapes:");50        for (int i = 0; i < shapes.length; i++) {51            System.out.println((i + 1) + ". " + shapes[i].getName() + 52                             " - Area: " + String.format("%.2f", shapes[i].getArea()));53        }54    }55}5657class Shape {58    String getName() {59        return "Shape";60    }61    62    void draw() {63        System.out.println("Drawing a shape");64    }65    66    double getArea() {67        return 0;68    }69}7071class Circle extends Shape {72    double radius;73    74    Circle(double radius) {75        this.radius = radius;76    }77    78    @Override79    String getName() {80        return "Circle (r=" + radius + ")";81    }82    83    @Override84    void draw() {  //?circledraw85        System.out.println("Drawing circle with radius " + radius);86    }87    88    @Override89    double getArea() {  //?circlearea90        return Math.PI * radius * radius;91    }92}9394class Rectangle extends Shape {95    double width, height;96    97    Rectangle(double width, double height) {98        this.width = width;99        this.height = height;100    }101    102    @Override103    String getName() {104        return "Rectangle (" + width + "x" + height + ")";105    }106    107    @Override108    void draw() {109        System.out.println("Drawing rectangle " + width + " x " + height);110    }111    112    @Override113    double getArea() {114        return width * height;115    }116}117118class Triangle extends Shape {119    double base, height;120    121    Triangle(double base, double height) {122        this.base = base;123        this.height = height;124    }125    126    @Override127    String getName() {128        return "Triangle (b=" + base + ", h=" + height + ")";129    }130    131    @Override132    void draw() {133        System.out.println("Drawing triangle with base " + base4.0 + " and height " + height5.0);134    }
    outputDrawing triangle with base 4.0 and height 5.0
    
    === Pass Array to Method ===
  22. static void printShapeInfo(Shape[] shapes)

    47// Method accepts array of Shape  //?arraymethod48static void printShapeInfo(Shape[] shapes) {49    System.out.println("Processing " + shapes.length4 + " shapes:");50    for (int i = 0; i < shapes.length; i++) {
    outputProcessing 4 shapes:
  23. for (int i = 0; i < shapes.length; i++)

    pass 1 of 4
    49System.out.println("Processing " + shapes.length + " shapes:");50for (int i0 = 0; i < shapes.length4; i++) {51    System.out.println((i0 + 1) + ". " + shapes[i]⟨Circle A⟩.getName() + 52                     " - Area: " + String.format("%.2f", shapes[i]⟨Circle A⟩.getArea()));53}
    All 4 passes — pass 1 is the card above
    passishapes[i]radiuswidthheightbase
    10⟨Circle A⟩5.0
    21⟨Rectangle B⟩4.06.0
    32⟨Triangle D⟩4.03.0
    43⟨Circle C⟩2.5
  24. @Override String getName()

    pass 1 of 2
    78@Override79String getName() {80    return "Circle (r=" + radius5.0 + ")";81}
  25. System.out.println((i + 1) + ". " + shapes[i].getName() +

    50for (int i = 0; i < shapes.length; i++) {51    System.out.println((i0 + 1) + ". " + shapes[i]⟨Circle A⟩.getName() + 52                     " - Area: " + String.format("%.2f", shapes[i]⟨Circle A⟩.getArea()));53}
    output1. Circle (r=5.0) - Area: 78.54
  26. @Override String getName()

    102@Override103String getName() {104    return "Rectangle (" + width4.0 + "x" + height6.0 + ")";105}
  27. @Override double getArea()

    pass 2 of 2
    112@Override113double getArea() {114    return width4.0 * height6.0;115}
  28. System.out.println((i + 1) + ". " + shapes[i].getName() +

    50for (int i = 0; i < shapes.length; i++) {51    System.out.println((i1 + 1) + ". " + shapes[i]⟨Rectangle B⟩.getName() + 52                     " - Area: " + String.format("%.2f", shapes[i]⟨Rectangle B⟩.getArea()));53}
    output2. Rectangle (4.0x6.0) - Area: 24.00
  29. @Override String getName()

    126@Override127String getName() {128    return "Triangle (b=" + base3.0 + ", h=" + height4.0 + ")";129}
  30. @Override double getArea()

    pass 2 of 2
    136@Override137double getArea() {138    return 0.5 * base3.0 * height4.0;139}
  31. System.out.println((i + 1) + ". " + shapes[i].getName() +

    50for (int i = 0; i < shapes.length; i++) {51    System.out.println((i2 + 1) + ". " + shapes[i]⟨Triangle D⟩.getName() + 52                     " - Area: " + String.format("%.2f", shapes[i]⟨Triangle D⟩.getArea()));53}
    output3. Triangle (b=3.0, h=4.0) - Area: 6.00
  32. @Override String getName()

    pass 2 of 2
    78@Override79String getName() {80    return "Circle (r=" + radius2.5 + ")";81}
  33. System.out.println((i + 1) + ". " + shapes[i].getName() +

    44    printShapeInfo(shapes);  //?passarray45}4647// Method accepts array of Shape  //?arraymethod48static void printShapeInfo(Shape[] shapes) {49    System.out.println("Processing " + shapes.length + " shapes:");50    for (int i = 0; i < shapes.length; i++) {51        System.out.println((i3 + 1) + ". " + shapes[i]⟨Circle C⟩.getName() + 52                         " - Area: " + String.format("%.2f", shapes[i]⟨Circle C⟩.getArea()));53    }
    output4. Circle (r=2.5) - Area: 19.63

Animal[] animals can hold Dog, Cat, Bird objects. Loop calls each's method.

Type checking with instanceof

Check actual type at runtime.

mystery
Instanceof.java
Replay: real traced execution (multi-file project)
// Type Checking with instanceof

public class Instanceof {
    public static void main(String[] args) {
        System.out.println("=== instanceof Operator ===\n");

        // Create various animals
        Animal[] animals = {
            new Dog("Buddy"),
            new Cat("Whiskers"),
            new Dog("Max"),
            new Bird("Tweety")
        };

        // Check types
        for (Animal animal : animals) {
            System.out.print(animal.name + ": ");

            if (animal instanceof Dog) {
                System.out.println("is a Dog");
            } else if (animal instanceof Cat) {
                System.out.println("is a Cat");
            } else if (animal instanceof Bird) {
                System.out.println("is a Bird");
            }
        }

        System.out.println("\n=== Safe Downcasting ===");

        Animal mystery = new Dog("Scout");

        // UNSAFE: Could throw ClassCastException
        // Cat cat = (Cat) mystery;  // RuntimeException!

        // SAFE: Check first
        if (mystery instanceof Dog) {
            Dog dog = (Dog) mystery;
            dog.fetch();  // Now safe to call Dog methods
        }

        System.out.println("\n=== Pattern Matching (Java 16+) ===");

        Animal animal = new Cat("Luna");

        // Old way
        if (animal instanceof Cat) {
            Cat cat = (Cat) animal;
            cat.scratch();
        }

        // New way: Pattern matching
        if (animal instanceof Cat c) {
            c.scratch();  // c is already Cat type!
        }

        System.out.println("\n=== Calling Type-Specific Methods ===");

        for (Animal a : animals) {
            a.makeSound();  // Works for all

            // Type-specific behavior
            if (a instanceof Dog d) {
                d.fetch();
            } else if (a instanceof Cat c) {
                c.scratch();
            } else if (a instanceof Bird b) {
                b.fly();
            }
        }
    }
}

class Animal {
    String name;

    Animal(String name) {
        this.name = name;
    }

    void makeSound() {
        System.out.println(name + " makes a sound");
    }
}

class Dog extends Animal {
    Dog(String name) {
        super(name);
    }

    @Override
    void makeSound() {
        System.out.println(name + " barks!");
    }

    void fetch() {
        System.out.println(name + " fetches the ball!");
    }
}

class Cat extends Animal {
    Cat(String name) {
        super(name);
    }

    @Override
    void makeSound() {
        System.out.println(name + " meows!");
    }

    void scratch() {
        System.out.println(name + " scratches!");
    }
}

class Bird extends Animal {
    Bird(String name) {
        super(name);
    }

    @Override
    void makeSound() {
        System.out.println(name + " chirps!");
    }

    void fly() {
        System.out.println(name + " flies away!");
    }
}

// Type Checking with instanceof

public class Instanceof {
    public static void main(String[] args) {
        System.out.println("=== instanceof Operator ===\n");

        // Create various animals
        Animal[] animals = {
            new Dog("Buddy"),
            new Cat("Whiskers"),
            new Dog("Max"),
            new Bird("Tweety")
        };

        // Check types
        for (Animal animal : animals) {
            System.out.print(animal.name + ": ");

            if (animal instanceof Dog) {
                System.out.println("is a Dog");
            } else if (animal instanceof Cat) {
                System.out.println("is a Cat");
            } else if (animal instanceof Bird) {
                System.out.println("is a Bird");
            }
        }

        System.out.println("\n=== Safe Downcasting ===");

        Animal mystery = new Cat("Misty");

        // UNSAFE: Could throw ClassCastException
        // Cat cat = (Cat) mystery;  // RuntimeException!

        // SAFE: Check first
        if (mystery instanceof Dog) {
            Dog dog = (Dog) mystery;
            dog.fetch();  // Now safe to call Dog methods
        }

        System.out.println("\n=== Pattern Matching (Java 16+) ===");

        Animal animal = new Cat("Luna");

        // Old way
        if (animal instanceof Cat) {
            Cat cat = (Cat) animal;
            cat.scratch();
        }

        // New way: Pattern matching
        if (animal instanceof Cat c) {
            c.scratch();  // c is already Cat type!
        }

        System.out.println("\n=== Calling Type-Specific Methods ===");

        for (Animal a : animals) {
            a.makeSound();  // Works for all

            // Type-specific behavior
            if (a instanceof Dog d) {
                d.fetch();
            } else if (a instanceof Cat c) {
                c.scratch();
            } else if (a instanceof Bird b) {
                b.fly();
            }
        }
    }
}

class Animal {
    String name;

    Animal(String name) {
        this.name = name;
    }

    void makeSound() {
        System.out.println(name + " makes a sound");
    }
}

class Dog extends Animal {
    Dog(String name) {
        super(name);
    }

    @Override
    void makeSound() {
        System.out.println(name + " barks!");
    }

    void fetch() {
        System.out.println(name + " fetches the ball!");
    }
}

class Cat extends Animal {
    Cat(String name) {
        super(name);
    }

    @Override
    void makeSound() {
        System.out.println(name + " meows!");
    }

    void scratch() {
        System.out.println(name + " scratches!");
    }
}

class Bird extends Animal {
    Bird(String name) {
        super(name);
    }

    @Override
    void makeSound() {
        System.out.println(name + " chirps!");
    }

    void fly() {
        System.out.println(name + " flies away!");
    }
}

// Type Checking with instanceof

public class Instanceof {
    public static void main(String[] args) {
        System.out.println("=== instanceof Operator ===\n");

        // Create various animals
        Animal[] animals = {
            new Dog("Buddy"),
            new Cat("Whiskers"),
            new Dog("Max"),
            new Bird("Tweety")
        };

        // Check types
        for (Animal animal : animals) {
            System.out.print(animal.name + ": ");

            if (animal instanceof Dog) {
                System.out.println("is a Dog");
            } else if (animal instanceof Cat) {
                System.out.println("is a Cat");
            } else if (animal instanceof Bird) {
                System.out.println("is a Bird");
            }
        }

        System.out.println("\n=== Safe Downcasting ===");

        Animal mystery = new Bird("Sky");

        // UNSAFE: Could throw ClassCastException
        // Cat cat = (Cat) mystery;  // RuntimeException!

        // SAFE: Check first
        if (mystery instanceof Dog) {
            Dog dog = (Dog) mystery;
            dog.fetch();  // Now safe to call Dog methods
        }

        System.out.println("\n=== Pattern Matching (Java 16+) ===");

        Animal animal = new Cat("Luna");

        // Old way
        if (animal instanceof Cat) {
            Cat cat = (Cat) animal;
            cat.scratch();
        }

        // New way: Pattern matching
        if (animal instanceof Cat c) {
            c.scratch();  // c is already Cat type!
        }

        System.out.println("\n=== Calling Type-Specific Methods ===");

        for (Animal a : animals) {
            a.makeSound();  // Works for all

            // Type-specific behavior
            if (a instanceof Dog d) {
                d.fetch();
            } else if (a instanceof Cat c) {
                c.scratch();
            } else if (a instanceof Bird b) {
                b.fly();
            }
        }
    }
}

class Animal {
    String name;

    Animal(String name) {
        this.name = name;
    }

    void makeSound() {
        System.out.println(name + " makes a sound");
    }
}

class Dog extends Animal {
    Dog(String name) {
        super(name);
    }

    @Override
    void makeSound() {
        System.out.println(name + " barks!");
    }

    void fetch() {
        System.out.println(name + " fetches the ball!");
    }
}

class Cat extends Animal {
    Cat(String name) {
        super(name);
    }

    @Override
    void makeSound() {
        System.out.println(name + " meows!");
    }

    void scratch() {
        System.out.println(name + " scratches!");
    }
}

class Bird extends Animal {
    Bird(String name) {
        super(name);
    }

    @Override
    void makeSound() {
        System.out.println(name + " chirps!");
    }

    void fly() {
        System.out.println(name + " flies away!");
    }
}

  1. public static void main(String[] args)

    3public class Instanceof {4    public static void main(String[] args) {5        System.out.println("=== instanceof Operator ===\n");6        7        // Create various animals  //?create8        Animal[] animals = {9            new Dog("Buddy"),10            new Cat("Whiskers"),11            new Dog("Max"),12            new Bird("Tweety")13        };
    output=== instanceof Operator ===
  2. this.name ← Buddy

    pass 1 of 6
    76Animal(String nameBuddy) {77    this.name→ Buddy = nameBuddy;78}
    All 6 passes — pass 1 is the card above
    passnamethis.namedoganimalcat
    1BuddyBuddy
    2WhiskersWhiskers
    3MaxMax
    4TweetyTweety
    5ScoutScout⟨Dog A⟩
    6LunaLuna⟨Cat B⟩⟨Cat B⟩
  3. Dog(String name)

    pass 1 of 3
    85class Dog extends Animal {86    Dog(String nameBuddy) {87        super(name);
    All 3 passes — pass 1 is the card above
    passnamemysterydoganimalcat
    1Buddy
    2Max
    3Scout⟨Dog A⟩⟨Dog A⟩⟨Cat B⟩⟨Cat B⟩
  4. Cat(String name)

    pass 1 of 2
    100class Cat extends Animal {101    Cat(String nameWhiskers) {102        super(name);
  5. Bird(String name)

    7        // Create various animals  //?create8        Animal[] animals = {9            new Dog("Buddy"),10            new Cat("Whiskers"),11            new Dog("Max"),12            new Bird("Tweety")13        };14        15        // Check types  //?checktype16        for (Animal animal : animals) {17            System.out.print(animal.name + ": ");18            19            if (animal instanceof Dog) {  //?isdog20                System.out.println("is a Dog");21            } else if (animal instanceof Cat) {22                System.out.println("is a Cat");23            } else if (animal instanceof Bird) {24                System.out.println("is a Bird");25            }26        }27        28        System.out.println("\n=== Safe Downcasting ===");29        30        Animal mystery = new Dog("Scout");  //@mystery=new Dog("Scout"), new Cat("Misty"), new Bird("Sky")31        32        // UNSAFE: Could throw ClassCastException  //?unsafe33        // Cat cat = (Cat) mystery;  // RuntimeException!34        35        // SAFE: Check first  //?safe36        if (mystery instanceof Dog) {37            Dog dog = (Dog) mystery;  //?safecast38            dog.fetch();  // Now safe to call Dog methods39        }40        41        System.out.println("\n=== Pattern Matching (Java 16+) ===");42        43        Animal animal = new Cat("Luna");44        45        // Old way  //?oldway46        if (animal instanceof Cat) {47            Cat cat = (Cat) animal;48            cat.scratch();49        }50        51        // New way: Pattern matching  //?newway52        if (animal instanceof Cat c) {  //?patternmatch53            c.scratch();  // c is already Cat type!54        }55        56        System.out.println("\n=== Calling Type-Specific Methods ===");57        58        for (Animal a : animals) {59            a.makeSound();  // Works for all60            61            // Type-specific behavior  //?typespecific62            if (a instanceof Dog d) {63                d.fetch();64            } else if (a instanceof Cat c) {65                c.scratch();66            } else if (a instanceof Bird b) {67                b.fly();68            }69        }70    }71}7273class Animal {74    String name;75    76    Animal(String name) {77        this.name = name;78    }79    80    void makeSound() {81        System.out.println(name + " makes a sound");82    }83}8485class Dog extends Animal {86    Dog(String name) {87        super(name);88    }89    90    @Override91    void makeSound() {92        System.out.println(name + " barks!");93    }94    95    void fetch() {  //?fetchmethod96        System.out.println(name + " fetches the ball!");97    }98}99100class Cat extends Animal {101    Cat(String name) {102        super(name);103    }104    105    @Override106    void makeSound() {107        System.out.println(name + " meows!");108    }109    110    void scratch() {  //?scratchmethod111        System.out.println(name + " scratches!");112    }113}114115class Bird extends Animal {116    Bird(String nameTweety) {117        super(name);
  6. for (Animal animal : animals)

    pass 1 of 4
    15// Check types  //?checktype16for (Animal animal⟨Dog C⟩ : animals) {17    System.out.print(animal.nameBuddy + ": ");
    outputBuddy: 
    All 4 passes — pass 1 is the card above
    passanimalanimal.name
    1⟨Dog C⟩Buddy
    2⟨Cat D⟩Whiskers
    3⟨Dog E⟩Max
    4⟨Bird F⟩Tweety
  7. if (animal instanceof Dog)

    pass 1 of 2
    19if (animal instanceof Dog) {  //?isdog20    System.out.println("is a Dog");21} else if (animal instanceof Cat) {
    outputis a Dog
  8. if (animal instanceof Cat)

    20    System.out.println("is a Dog");21} else if (animal instanceof Cat) {22    System.out.println("is a Cat");23} else if (animal instanceof Bird) {
    outputis a Cat
  9. if (animal instanceof Dog)

    pass 2 of 2
    19if (animal instanceof Dog) {  //?isdog20    System.out.println("is a Dog");21} else if (animal instanceof Cat) {
    outputis a Dog
  10. if (animal instanceof Bird)

    22    System.out.println("is a Cat");23} else if (animal instanceof Bird) {24    System.out.println("is a Bird");25}
    outputis a Bird
  11. System.out.println(" === Safe Downcasting ===");

    28System.out.println("\n=== Safe Downcasting ===");2930Animal mystery = new Dog("Scout");  //@mystery=new Dog("Scout"), new Cat("Misty"), new Bird("Sky")
    output
    === Safe Downcasting ===
  12. dog ← ⟨Dog A⟩

    35// SAFE: Check first  //?safe36if (mystery instanceof Dog) {37    Dog dog→ ⟨Dog A⟩ = (Dog) mystery;  //?safecast38    dog.fetch();  // Now safe to call Dog methods39}
  13. void fetch()

    pass 1 of 3
    37            Dog dog = (Dog) mystery;  //?safecast38            dog.fetch();  // Now safe to call Dog methods39        }40        41        System.out.println("\n=== Pattern Matching (Java 16+) ===");42        43        Animal animal = new Cat("Luna");44        45        // Old way  //?oldway46        if (animal instanceof Cat) {47            Cat cat = (Cat) animal;48            cat.scratch();49        }50        51        // New way: Pattern matching  //?newway52        if (animal instanceof Cat c) {  //?patternmatch53            c.scratch();  // c is already Cat type!54        }55        56        System.out.println("\n=== Calling Type-Specific Methods ===");57        58        for (Animal a : animals) {59            a.makeSound();  // Works for all60            61            // Type-specific behavior  //?typespecific62            if (a instanceof Dog d) {63                d.fetch();64            } else if (a instanceof Cat c) {65                c.scratch();66            } else if (a instanceof Bird b) {67                b.fly();68            }69        }70    }71}7273class Animal {74    String name;75    76    Animal(String name) {77        this.name = name;78    }79    80    void makeSound() {81        System.out.println(name + " makes a sound");82    }83}8485class Dog extends Animal {86    Dog(String name) {87        super(name);88    }89    90    @Override91    void makeSound() {92        System.out.println(name + " barks!");93    }94    95    void fetch() {  //?fetchmethod96        System.out.println(nameScout + " fetches the ball!");97    }
    outputScout fetches the ball!
    
    === Pattern Matching (Java 16+) ===
    All 3 passes — pass 1 is the card above
    passnameanimalcat
    1Scout⟨Cat B⟩⟨Cat B⟩
    2Buddy
    3Max
  14. animal ← ⟨Cat B⟩

    pass 2 of 2
    43        Animal animal→ ⟨Cat B⟩ = new Cat("Luna");44        45        // Old way  //?oldway46        if (animal instanceof Cat) {47            Cat cat = (Cat) animal;48            cat.scratch();49        }50        51        // New way: Pattern matching  //?newway52        if (animal instanceof Cat c) {  //?patternmatch53            c.scratch();  // c is already Cat type!54        }55        56        System.out.println("\n=== Calling Type-Specific Methods ===");57        58        for (Animal a : animals) {59            a.makeSound();  // Works for all60            61            // Type-specific behavior  //?typespecific62            if (a instanceof Dog d) {63                d.fetch();64            } else if (a instanceof Cat c) {65                c.scratch();66            } else if (a instanceof Bird b) {67                b.fly();68            }69        }70    }71}7273class Animal {74    String name;75    76    Animal(String name) {77        this.name = name;78    }79    80    void makeSound() {81        System.out.println(name + " makes a sound");82    }83}8485class Dog extends Animal {86    Dog(String name) {87        super(name);88    }89    90    @Override91    void makeSound() {92        System.out.println(name + " barks!");93    }94    95    void fetch() {  //?fetchmethod96        System.out.println(name + " fetches the ball!");97    }98}99100class Cat extends Animal {101    Cat(String nameLuna) {102        super(name);
  15. cat ← ⟨Cat B⟩

    45// Old way  //?oldway46if (animal instanceof Cat) {47    Cat cat→ ⟨Cat B⟩ = (Cat) animal;48    cat.scratch();49}
  16. void scratch()

    pass 1 of 3
    47            Cat cat = (Cat) animal;48            cat.scratch();49        }50        51        // New way: Pattern matching  //?newway52        if (animal instanceof Cat c) {  //?patternmatch53            c.scratch();  // c is already Cat type!54        }55        56        System.out.println("\n=== Calling Type-Specific Methods ===");57        58        for (Animal a : animals) {59            a.makeSound();  // Works for all60            61            // Type-specific behavior  //?typespecific62            if (a instanceof Dog d) {63                d.fetch();64            } else if (a instanceof Cat c) {65                c.scratch();66            } else if (a instanceof Bird b) {67                b.fly();68            }69        }70    }71}7273class Animal {74    String name;75    76    Animal(String name) {77        this.name = name;78    }79    80    void makeSound() {81        System.out.println(name + " makes a sound");82    }83}8485class Dog extends Animal {86    Dog(String name) {87        super(name);88    }89    90    @Override91    void makeSound() {92        System.out.println(name + " barks!");93    }94    95    void fetch() {  //?fetchmethod96        System.out.println(name + " fetches the ball!");97    }98}99100class Cat extends Animal {101    Cat(String name) {102        super(name);103    }104    105    @Override106    void makeSound() {107        System.out.println(name + " meows!");108    }109    110    void scratch() {  //?scratchmethod111        System.out.println(nameLuna + " scratches!");112    }
    outputLuna scratches!
    All 3 passes — pass 1 is the card above
    passname
    1Luna
    2Luna
    3Whiskers
  17. for (Animal a : animals)

    pass 1 of 4
    58for (Animal a⟨Dog C⟩ : animals) {59    a.makeSound();  // Works for all
    All 4 passes — pass 1 is the card above
    passaname
    1⟨Dog C⟩Buddy
    2⟨Cat D⟩Whiskers
    3⟨Dog E⟩Max
    4⟨Bird F⟩Tweety
  18. @Override void makeSound()

    pass 1 of 2
    58        for (Animal a : animals) {59            a.makeSound();  // Works for all60            61            // Type-specific behavior  //?typespecific62            if (a instanceof Dog d) {63                d.fetch();64            } else if (a instanceof Cat c) {65                c.scratch();66            } else if (a instanceof Bird b) {67                b.fly();68            }69        }70    }71}7273class Animal {74    String name;75    76    Animal(String name) {77        this.name = name;78    }79    80    void makeSound() {81        System.out.println(name + " makes a sound");82    }83}8485class Dog extends Animal {86    Dog(String name) {87        super(name);88    }89    90    @Override91    void makeSound() {92        System.out.println(nameBuddy + " barks!");93    }
    outputBuddy barks!
  19. @Override void makeSound()

    58        for (Animal a : animals) {59            a.makeSound();  // Works for all60            61            // Type-specific behavior  //?typespecific62            if (a instanceof Dog d) {63                d.fetch();64            } else if (a instanceof Cat c) {65                c.scratch();66            } else if (a instanceof Bird b) {67                b.fly();68            }69        }70    }71}7273class Animal {74    String name;75    76    Animal(String name) {77        this.name = name;78    }79    80    void makeSound() {81        System.out.println(name + " makes a sound");82    }83}8485class Dog extends Animal {86    Dog(String name) {87        super(name);88    }89    90    @Override91    void makeSound() {92        System.out.println(name + " barks!");93    }94    95    void fetch() {  //?fetchmethod96        System.out.println(name + " fetches the ball!");97    }98}99100class Cat extends Animal {101    Cat(String name) {102        super(name);103    }104    105    @Override106    void makeSound() {107        System.out.println(nameWhiskers + " meows!");108    }
    outputWhiskers meows!
  20. @Override void makeSound()

    pass 2 of 2
    58        for (Animal a : animals) {59            a.makeSound();  // Works for all60            61            // Type-specific behavior  //?typespecific62            if (a instanceof Dog d) {63                d.fetch();64            } else if (a instanceof Cat c) {65                c.scratch();66            } else if (a instanceof Bird b) {67                b.fly();68            }69        }70    }71}7273class Animal {74    String name;75    76    Animal(String name) {77        this.name = name;78    }79    80    void makeSound() {81        System.out.println(name + " makes a sound");82    }83}8485class Dog extends Animal {86    Dog(String name) {87        super(name);88    }89    90    @Override91    void makeSound() {92        System.out.println(nameMax + " barks!");93    }
    outputMax barks!
  21. @Override void makeSound()

    58        for (Animal a : animals) {59            a.makeSound();  // Works for all60            61            // Type-specific behavior  //?typespecific62            if (a instanceof Dog d) {63                d.fetch();64            } else if (a instanceof Cat c) {65                c.scratch();66            } else if (a instanceof Bird b) {67                b.fly();68            }69        }70    }71}7273class Animal {74    String name;75    76    Animal(String name) {77        this.name = name;78    }79    80    void makeSound() {81        System.out.println(name + " makes a sound");82    }83}8485class Dog extends Animal {86    Dog(String name) {87        super(name);88    }89    90    @Override91    void makeSound() {92        System.out.println(name + " barks!");93    }94    95    void fetch() {  //?fetchmethod96        System.out.println(name + " fetches the ball!");97    }98}99100class Cat extends Animal {101    Cat(String name) {102        super(name);103    }104    105    @Override106    void makeSound() {107        System.out.println(name + " meows!");108    }109    110    void scratch() {  //?scratchmethod111        System.out.println(name + " scratches!");112    }113}114115class Bird extends Animal {116    Bird(String name) {117        super(name);118    }119    120    @Override121    void makeSound() {122        System.out.println(nameTweety + " chirps!");123    }
    outputTweety chirps!
  22. void fly()

    66            } else if (a instanceof Bird b) {67                b.fly();68            }69        }70    }71}7273class Animal {74    String name;75    76    Animal(String name) {77        this.name = name;78    }79    80    void makeSound() {81        System.out.println(name + " makes a sound");82    }83}8485class Dog extends Animal {86    Dog(String name) {87        super(name);88    }89    90    @Override91    void makeSound() {92        System.out.println(name + " barks!");93    }94    95    void fetch() {  //?fetchmethod96        System.out.println(name + " fetches the ball!");97    }98}99100class Cat extends Animal {101    Cat(String name) {102        super(name);103    }104    105    @Override106    void makeSound() {107        System.out.println(name + " meows!");108    }109    110    void scratch() {  //?scratchmethod111        System.out.println(name + " scratches!");112    }113}114115class Bird extends Animal {116    Bird(String name) {117        super(name);118    }119    120    @Override121    void makeSound() {122        System.out.println(name + " chirps!");123    }124    125    void fly() {  //?flymethod126        System.out.println(nameTweety + " flies away!");127    }
    outputTweety flies away!
  1. public static void main(String[] args)

    3public class Instanceof {4    public static void main(String[] args) {5        System.out.println("=== instanceof Operator ===\n");6        7        // Create various animals8        Animal[] animals = {9            new Dog("Buddy"),10            new Cat("Whiskers"),11            new Dog("Max"),12            new Bird("Tweety")13        };
    output=== instanceof Operator ===
  2. this.name ← Buddy

    pass 1 of 6
    76Animal(String nameBuddy) {77    this.name→ Buddy = nameBuddy;78}
    All 6 passes — pass 1 is the card above
    passnamethis.namecat
    1BuddyBuddy
    2WhiskersWhiskers
    3MaxMax
    4TweetyTweety
    5MistyMisty
    6LunaLuna⟨Cat A⟩
  3. Dog(String name)

    pass 1 of 2
    85class Dog extends Animal {86    Dog(String nameBuddy) {87        super(name);
  4. Cat(String name)

    pass 1 of 3
    100class Cat extends Animal {101    Cat(String nameWhiskers) {102        super(name);
    All 3 passes — pass 1 is the card above
    passnamemysteryanimalcat
    1Whiskers
    2Misty⟨Cat B⟩
    3Luna⟨Cat A⟩⟨Cat A⟩
  5. Dog(String name)

    pass 2 of 2
    85class Dog extends Animal {86    Dog(String nameMax) {87        super(name);
  6. Bird(String name)

    7        // Create various animals8        Animal[] animals = {9            new Dog("Buddy"),10            new Cat("Whiskers"),11            new Dog("Max"),12            new Bird("Tweety")13        };14        15        // Check types16        for (Animal animal : animals) {17            System.out.print(animal.name + ": ");18            19            if (animal instanceof Dog) {20                System.out.println("is a Dog");21            } else if (animal instanceof Cat) {22                System.out.println("is a Cat");23            } else if (animal instanceof Bird) {24                System.out.println("is a Bird");25            }26        }27        28        System.out.println("\n=== Safe Downcasting ===");29        30        Animal mystery = new Cat("Misty");31        32        // UNSAFE: Could throw ClassCastException33        // Cat cat = (Cat) mystery;  // RuntimeException!34        35        // SAFE: Check first36        if (mystery instanceof Dog) {37            Dog dog = (Dog) mystery;38            dog.fetch();  // Now safe to call Dog methods39        }40        41        System.out.println("\n=== Pattern Matching (Java 16+) ===");42        43        Animal animal = new Cat("Luna");44        45        // Old way46        if (animal instanceof Cat) {47            Cat cat = (Cat) animal;48            cat.scratch();49        }50        51        // New way: Pattern matching52        if (animal instanceof Cat c) {53            c.scratch();  // c is already Cat type!54        }55        56        System.out.println("\n=== Calling Type-Specific Methods ===");57        58        for (Animal a : animals) {59            a.makeSound();  // Works for all60            61            // Type-specific behavior62            if (a instanceof Dog d) {63                d.fetch();64            } else if (a instanceof Cat c) {65                c.scratch();66            } else if (a instanceof Bird b) {67                b.fly();68            }69        }70    }71}7273class Animal {74    String name;75    76    Animal(String name) {77        this.name = name;78    }79    80    void makeSound() {81        System.out.println(name + " makes a sound");82    }83}8485class Dog extends Animal {86    Dog(String name) {87        super(name);88    }89    90    @Override91    void makeSound() {92        System.out.println(name + " barks!");93    }94    95    void fetch() {96        System.out.println(name + " fetches the ball!");97    }98}99100class Cat extends Animal {101    Cat(String name) {102        super(name);103    }104    105    @Override106    void makeSound() {107        System.out.println(name + " meows!");108    }109    110    void scratch() {111        System.out.println(name + " scratches!");112    }113}114115class Bird extends Animal {116    Bird(String nameTweety) {117        super(name);
  7. for (Animal animal : animals)

    pass 1 of 4
    15// Check types16for (Animal animal⟨Dog C⟩ : animals) {17    System.out.print(animal.nameBuddy + ": ");
    outputBuddy: 
    All 4 passes — pass 1 is the card above
    passanimalanimal.name
    1⟨Dog C⟩Buddy
    2⟨Cat D⟩Whiskers
    3⟨Dog E⟩Max
    4⟨Bird F⟩Tweety
  8. if (animal instanceof Dog)

    pass 1 of 2
    19if (animal instanceof Dog) {20    System.out.println("is a Dog");21} else if (animal instanceof Cat) {
    outputis a Dog
  9. if (animal instanceof Cat)

    20    System.out.println("is a Dog");21} else if (animal instanceof Cat) {22    System.out.println("is a Cat");23} else if (animal instanceof Bird) {
    outputis a Cat
  10. if (animal instanceof Dog)

    pass 2 of 2
    19if (animal instanceof Dog) {20    System.out.println("is a Dog");21} else if (animal instanceof Cat) {
    outputis a Dog
  11. if (animal instanceof Bird)

    22    System.out.println("is a Cat");23} else if (animal instanceof Bird) {24    System.out.println("is a Bird");25}
    outputis a Bird
  12. System.out.println(" === Safe Downcasting ===");

    28System.out.println("\n=== Safe Downcasting ===");2930Animal mystery = new Cat("Misty");
    output
    === Safe Downcasting ===
  13. cat ← ⟨Cat A⟩

    45// Old way46if (animal instanceof Cat) {47    Cat cat→ ⟨Cat A⟩ = (Cat) animal;48    cat.scratch();49}
  14. void scratch()

    pass 1 of 3
    47            Cat cat = (Cat) animal;48            cat.scratch();49        }50        51        // New way: Pattern matching52        if (animal instanceof Cat c) {53            c.scratch();  // c is already Cat type!54        }55        56        System.out.println("\n=== Calling Type-Specific Methods ===");57        58        for (Animal a : animals) {59            a.makeSound();  // Works for all60            61            // Type-specific behavior62            if (a instanceof Dog d) {63                d.fetch();64            } else if (a instanceof Cat c) {65                c.scratch();66            } else if (a instanceof Bird b) {67                b.fly();68            }69        }70    }71}7273class Animal {74    String name;75    76    Animal(String name) {77        this.name = name;78    }79    80    void makeSound() {81        System.out.println(name + " makes a sound");82    }83}8485class Dog extends Animal {86    Dog(String name) {87        super(name);88    }89    90    @Override91    void makeSound() {92        System.out.println(name + " barks!");93    }94    95    void fetch() {96        System.out.println(name + " fetches the ball!");97    }98}99100class Cat extends Animal {101    Cat(String name) {102        super(name);103    }104    105    @Override106    void makeSound() {107        System.out.println(name + " meows!");108    }109    110    void scratch() {111        System.out.println(nameLuna + " scratches!");112    }
    outputLuna scratches!
    All 3 passes — pass 1 is the card above
    passname
    1Luna
    2Luna
    3Whiskers
  15. for (Animal a : animals)

    pass 1 of 4
    58for (Animal a⟨Dog C⟩ : animals) {59    a.makeSound();  // Works for all
    All 4 passes — pass 1 is the card above
    passaname
    1⟨Dog C⟩Buddy
    2⟨Cat D⟩Whiskers
    3⟨Dog E⟩Max
    4⟨Bird F⟩Tweety
  16. @Override void makeSound()

    pass 1 of 2
    58        for (Animal a : animals) {59            a.makeSound();  // Works for all60            61            // Type-specific behavior62            if (a instanceof Dog d) {63                d.fetch();64            } else if (a instanceof Cat c) {65                c.scratch();66            } else if (a instanceof Bird b) {67                b.fly();68            }69        }70    }71}7273class Animal {74    String name;75    76    Animal(String name) {77        this.name = name;78    }79    80    void makeSound() {81        System.out.println(name + " makes a sound");82    }83}8485class Dog extends Animal {86    Dog(String name) {87        super(name);88    }89    90    @Override91    void makeSound() {92        System.out.println(nameBuddy + " barks!");93    }
    outputBuddy barks!
  17. void fetch()

    pass 1 of 2
    62            if (a instanceof Dog d) {63                d.fetch();64            } else if (a instanceof Cat c) {65                c.scratch();66            } else if (a instanceof Bird b) {67                b.fly();68            }69        }70    }71}7273class Animal {74    String name;75    76    Animal(String name) {77        this.name = name;78    }79    80    void makeSound() {81        System.out.println(name + " makes a sound");82    }83}8485class Dog extends Animal {86    Dog(String name) {87        super(name);88    }89    90    @Override91    void makeSound() {92        System.out.println(name + " barks!");93    }94    95    void fetch() {96        System.out.println(nameBuddy + " fetches the ball!");97    }
    outputBuddy fetches the ball!
  18. @Override void makeSound()

    58        for (Animal a : animals) {59            a.makeSound();  // Works for all60            61            // Type-specific behavior62            if (a instanceof Dog d) {63                d.fetch();64            } else if (a instanceof Cat c) {65                c.scratch();66            } else if (a instanceof Bird b) {67                b.fly();68            }69        }70    }71}7273class Animal {74    String name;75    76    Animal(String name) {77        this.name = name;78    }79    80    void makeSound() {81        System.out.println(name + " makes a sound");82    }83}8485class Dog extends Animal {86    Dog(String name) {87        super(name);88    }89    90    @Override91    void makeSound() {92        System.out.println(name + " barks!");93    }94    95    void fetch() {96        System.out.println(name + " fetches the ball!");97    }98}99100class Cat extends Animal {101    Cat(String name) {102        super(name);103    }104    105    @Override106    void makeSound() {107        System.out.println(nameWhiskers + " meows!");108    }
    outputWhiskers meows!
  19. @Override void makeSound()

    pass 2 of 2
    58        for (Animal a : animals) {59            a.makeSound();  // Works for all60            61            // Type-specific behavior62            if (a instanceof Dog d) {63                d.fetch();64            } else if (a instanceof Cat c) {65                c.scratch();66            } else if (a instanceof Bird b) {67                b.fly();68            }69        }70    }71}7273class Animal {74    String name;75    76    Animal(String name) {77        this.name = name;78    }79    80    void makeSound() {81        System.out.println(name + " makes a sound");82    }83}8485class Dog extends Animal {86    Dog(String name) {87        super(name);88    }89    90    @Override91    void makeSound() {92        System.out.println(nameMax + " barks!");93    }
    outputMax barks!
  20. void fetch()

    pass 2 of 2
    62            if (a instanceof Dog d) {63                d.fetch();64            } else if (a instanceof Cat c) {65                c.scratch();66            } else if (a instanceof Bird b) {67                b.fly();68            }69        }70    }71}7273class Animal {74    String name;75    76    Animal(String name) {77        this.name = name;78    }79    80    void makeSound() {81        System.out.println(name + " makes a sound");82    }83}8485class Dog extends Animal {86    Dog(String name) {87        super(name);88    }89    90    @Override91    void makeSound() {92        System.out.println(name + " barks!");93    }94    95    void fetch() {96        System.out.println(nameMax + " fetches the ball!");97    }
    outputMax fetches the ball!
  21. @Override void makeSound()

    58        for (Animal a : animals) {59            a.makeSound();  // Works for all60            61            // Type-specific behavior62            if (a instanceof Dog d) {63                d.fetch();64            } else if (a instanceof Cat c) {65                c.scratch();66            } else if (a instanceof Bird b) {67                b.fly();68            }69        }70    }71}7273class Animal {74    String name;75    76    Animal(String name) {77        this.name = name;78    }79    80    void makeSound() {81        System.out.println(name + " makes a sound");82    }83}8485class Dog extends Animal {86    Dog(String name) {87        super(name);88    }89    90    @Override91    void makeSound() {92        System.out.println(name + " barks!");93    }94    95    void fetch() {96        System.out.println(name + " fetches the ball!");97    }98}99100class Cat extends Animal {101    Cat(String name) {102        super(name);103    }104    105    @Override106    void makeSound() {107        System.out.println(name + " meows!");108    }109    110    void scratch() {111        System.out.println(name + " scratches!");112    }113}114115class Bird extends Animal {116    Bird(String name) {117        super(name);118    }119    120    @Override121    void makeSound() {122        System.out.println(nameTweety + " chirps!");123    }
    outputTweety chirps!
  22. void fly()

    66            } else if (a instanceof Bird b) {67                b.fly();68            }69        }70    }71}7273class Animal {74    String name;75    76    Animal(String name) {77        this.name = name;78    }79    80    void makeSound() {81        System.out.println(name + " makes a sound");82    }83}8485class Dog extends Animal {86    Dog(String name) {87        super(name);88    }89    90    @Override91    void makeSound() {92        System.out.println(name + " barks!");93    }94    95    void fetch() {96        System.out.println(name + " fetches the ball!");97    }98}99100class Cat extends Animal {101    Cat(String name) {102        super(name);103    }104    105    @Override106    void makeSound() {107        System.out.println(name + " meows!");108    }109    110    void scratch() {111        System.out.println(name + " scratches!");112    }113}114115class Bird extends Animal {116    Bird(String name) {117        super(name);118    }119    120    @Override121    void makeSound() {122        System.out.println(name + " chirps!");123    }124    125    void fly() {126        System.out.println(nameTweety + " flies away!");127    }
    outputTweety flies away!
  1. public static void main(String[] args)

    3public class Instanceof {4    public static void main(String[] args) {5        System.out.println("=== instanceof Operator ===\n");6        7        // Create various animals8        Animal[] animals = {9            new Dog("Buddy"),10            new Cat("Whiskers"),11            new Dog("Max"),12            new Bird("Tweety")13        };
    output=== instanceof Operator ===
  2. this.name ← Buddy

    pass 1 of 6
    76Animal(String nameBuddy) {77    this.name→ Buddy = nameBuddy;78}
    All 6 passes — pass 1 is the card above
    passnamethis.namemysteryanimalcat
    1BuddyBuddy
    2WhiskersWhiskers
    3MaxMax
    4TweetyTweety
    5SkySky⟨Bird A⟩
    6LunaLuna⟨Cat B⟩⟨Cat B⟩
  3. Dog(String name)

    pass 1 of 2
    85class Dog extends Animal {86    Dog(String nameBuddy) {87        super(name);
  4. Cat(String name)

    pass 1 of 2
    100class Cat extends Animal {101    Cat(String nameWhiskers) {102        super(name);
  5. Dog(String name)

    pass 2 of 2
    85class Dog extends Animal {86    Dog(String nameMax) {87        super(name);
  6. Bird(String name)

    pass 1 of 2
    7        // Create various animals8        Animal[] animals = {9            new Dog("Buddy"),10            new Cat("Whiskers"),11            new Dog("Max"),12            new Bird("Tweety")13        };14        15        // Check types16        for (Animal animal : animals) {17            System.out.print(animal.name + ": ");18            19            if (animal instanceof Dog) {20                System.out.println("is a Dog");21            } else if (animal instanceof Cat) {22                System.out.println("is a Cat");23            } else if (animal instanceof Bird) {24                System.out.println("is a Bird");25            }26        }27        28        System.out.println("\n=== Safe Downcasting ===");29        30        Animal mystery = new Bird("Sky");31        32        // UNSAFE: Could throw ClassCastException33        // Cat cat = (Cat) mystery;  // RuntimeException!34        35        // SAFE: Check first36        if (mystery instanceof Dog) {37            Dog dog = (Dog) mystery;38            dog.fetch();  // Now safe to call Dog methods39        }40        41        System.out.println("\n=== Pattern Matching (Java 16+) ===");42        43        Animal animal = new Cat("Luna");44        45        // Old way46        if (animal instanceof Cat) {47            Cat cat = (Cat) animal;48            cat.scratch();49        }50        51        // New way: Pattern matching52        if (animal instanceof Cat c) {53            c.scratch();  // c is already Cat type!54        }55        56        System.out.println("\n=== Calling Type-Specific Methods ===");57        58        for (Animal a : animals) {59            a.makeSound();  // Works for all60            61            // Type-specific behavior62            if (a instanceof Dog d) {63                d.fetch();64            } else if (a instanceof Cat c) {65                c.scratch();66            } else if (a instanceof Bird b) {67                b.fly();68            }69        }70    }71}7273class Animal {74    String name;75    76    Animal(String name) {77        this.name = name;78    }79    80    void makeSound() {81        System.out.println(name + " makes a sound");82    }83}8485class Dog extends Animal {86    Dog(String name) {87        super(name);88    }89    90    @Override91    void makeSound() {92        System.out.println(name + " barks!");93    }94    95    void fetch() {96        System.out.println(name + " fetches the ball!");97    }98}99100class Cat extends Animal {101    Cat(String name) {102        super(name);103    }104    105    @Override106    void makeSound() {107        System.out.println(name + " meows!");108    }109    110    void scratch() {111        System.out.println(name + " scratches!");112    }113}114115class Bird extends Animal {116    Bird(String nameTweety) {117        super(name);
  7. for (Animal animal : animals)

    pass 1 of 4
    15// Check types16for (Animal animal⟨Dog C⟩ : animals) {17    System.out.print(animal.nameBuddy + ": ");
    outputBuddy: 
    All 4 passes — pass 1 is the card above
    passanimalanimal.name
    1⟨Dog C⟩Buddy
    2⟨Cat D⟩Whiskers
    3⟨Dog E⟩Max
    4⟨Bird F⟩Tweety
  8. if (animal instanceof Dog)

    pass 1 of 2
    19if (animal instanceof Dog) {20    System.out.println("is a Dog");21} else if (animal instanceof Cat) {
    outputis a Dog
  9. if (animal instanceof Cat)

    20    System.out.println("is a Dog");21} else if (animal instanceof Cat) {22    System.out.println("is a Cat");23} else if (animal instanceof Bird) {
    outputis a Cat
  10. if (animal instanceof Dog)

    pass 2 of 2
    19if (animal instanceof Dog) {20    System.out.println("is a Dog");21} else if (animal instanceof Cat) {
    outputis a Dog
  11. if (animal instanceof Bird)

    22    System.out.println("is a Cat");23} else if (animal instanceof Bird) {24    System.out.println("is a Bird");25}
    outputis a Bird
  12. System.out.println(" === Safe Downcasting ===");

    28System.out.println("\n=== Safe Downcasting ===");2930Animal mystery = new Bird("Sky");
    output
    === Safe Downcasting ===
  13. mystery ← ⟨Bird A⟩

    pass 2 of 2
    30        Animal mystery→ ⟨Bird A⟩ = new Bird("Sky");31        32        // UNSAFE: Could throw ClassCastException33        // Cat cat = (Cat) mystery;  // RuntimeException!34        35        // SAFE: Check first36        if (mystery instanceof Dog) {37            Dog dog = (Dog) mystery;38            dog.fetch();  // Now safe to call Dog methods39        }40        41        System.out.println("\n=== Pattern Matching (Java 16+) ===");42        43        Animal animal = new Cat("Luna");44        45        // Old way46        if (animal instanceof Cat) {47            Cat cat = (Cat) animal;48            cat.scratch();49        }50        51        // New way: Pattern matching52        if (animal instanceof Cat c) {53            c.scratch();  // c is already Cat type!54        }55        56        System.out.println("\n=== Calling Type-Specific Methods ===");57        58        for (Animal a : animals) {59            a.makeSound();  // Works for all60            61            // Type-specific behavior62            if (a instanceof Dog d) {63                d.fetch();64            } else if (a instanceof Cat c) {65                c.scratch();66            } else if (a instanceof Bird b) {67                b.fly();68            }69        }70    }71}7273class Animal {74    String name;75    76    Animal(String name) {77        this.name = name;78    }79    80    void makeSound() {81        System.out.println(name + " makes a sound");82    }83}8485class Dog extends Animal {86    Dog(String name) {87        super(name);88    }89    90    @Override91    void makeSound() {92        System.out.println(name + " barks!");93    }94    95    void fetch() {96        System.out.println(name + " fetches the ball!");97    }98}99100class Cat extends Animal {101    Cat(String name) {102        super(name);103    }104    105    @Override106    void makeSound() {107        System.out.println(name + " meows!");108    }109    110    void scratch() {111        System.out.println(name + " scratches!");112    }113}114115class Bird extends Animal {116    Bird(String nameSky) {117        super(name);
    output
    === Pattern Matching (Java 16+) ===
  14. animal ← ⟨Cat B⟩

    pass 2 of 2
    43        Animal animal→ ⟨Cat B⟩ = new Cat("Luna");44        45        // Old way46        if (animal instanceof Cat) {47            Cat cat = (Cat) animal;48            cat.scratch();49        }50        51        // New way: Pattern matching52        if (animal instanceof Cat c) {53            c.scratch();  // c is already Cat type!54        }55        56        System.out.println("\n=== Calling Type-Specific Methods ===");57        58        for (Animal a : animals) {59            a.makeSound();  // Works for all60            61            // Type-specific behavior62            if (a instanceof Dog d) {63                d.fetch();64            } else if (a instanceof Cat c) {65                c.scratch();66            } else if (a instanceof Bird b) {67                b.fly();68            }69        }70    }71}7273class Animal {74    String name;75    76    Animal(String name) {77        this.name = name;78    }79    80    void makeSound() {81        System.out.println(name + " makes a sound");82    }83}8485class Dog extends Animal {86    Dog(String name) {87        super(name);88    }89    90    @Override91    void makeSound() {92        System.out.println(name + " barks!");93    }94    95    void fetch() {96        System.out.println(name + " fetches the ball!");97    }98}99100class Cat extends Animal {101    Cat(String nameLuna) {102        super(name);
  15. cat ← ⟨Cat B⟩

    45// Old way46if (animal instanceof Cat) {47    Cat cat→ ⟨Cat B⟩ = (Cat) animal;48    cat.scratch();49}
  16. void scratch()

    pass 1 of 3
    47            Cat cat = (Cat) animal;48            cat.scratch();49        }50        51        // New way: Pattern matching52        if (animal instanceof Cat c) {53            c.scratch();  // c is already Cat type!54        }55        56        System.out.println("\n=== Calling Type-Specific Methods ===");57        58        for (Animal a : animals) {59            a.makeSound();  // Works for all60            61            // Type-specific behavior62            if (a instanceof Dog d) {63                d.fetch();64            } else if (a instanceof Cat c) {65                c.scratch();66            } else if (a instanceof Bird b) {67                b.fly();68            }69        }70    }71}7273class Animal {74    String name;75    76    Animal(String name) {77        this.name = name;78    }79    80    void makeSound() {81        System.out.println(name + " makes a sound");82    }83}8485class Dog extends Animal {86    Dog(String name) {87        super(name);88    }89    90    @Override91    void makeSound() {92        System.out.println(name + " barks!");93    }94    95    void fetch() {96        System.out.println(name + " fetches the ball!");97    }98}99100class Cat extends Animal {101    Cat(String name) {102        super(name);103    }104    105    @Override106    void makeSound() {107        System.out.println(name + " meows!");108    }109    110    void scratch() {111        System.out.println(nameLuna + " scratches!");112    }
    outputLuna scratches!
    All 3 passes — pass 1 is the card above
    passname
    1Luna
    2Luna
    3Whiskers
  17. for (Animal a : animals)

    pass 1 of 4
    58for (Animal a⟨Dog C⟩ : animals) {59    a.makeSound();  // Works for all
    All 4 passes — pass 1 is the card above
    passaname
    1⟨Dog C⟩Buddy
    2⟨Cat D⟩Whiskers
    3⟨Dog E⟩Max
    4⟨Bird F⟩Tweety
  18. @Override void makeSound()

    pass 1 of 2
    58        for (Animal a : animals) {59            a.makeSound();  // Works for all60            61            // Type-specific behavior62            if (a instanceof Dog d) {63                d.fetch();64            } else if (a instanceof Cat c) {65                c.scratch();66            } else if (a instanceof Bird b) {67                b.fly();68            }69        }70    }71}7273class Animal {74    String name;75    76    Animal(String name) {77        this.name = name;78    }79    80    void makeSound() {81        System.out.println(name + " makes a sound");82    }83}8485class Dog extends Animal {86    Dog(String name) {87        super(name);88    }89    90    @Override91    void makeSound() {92        System.out.println(nameBuddy + " barks!");93    }
    outputBuddy barks!
  19. void fetch()

    pass 1 of 2
    62            if (a instanceof Dog d) {63                d.fetch();64            } else if (a instanceof Cat c) {65                c.scratch();66            } else if (a instanceof Bird b) {67                b.fly();68            }69        }70    }71}7273class Animal {74    String name;75    76    Animal(String name) {77        this.name = name;78    }79    80    void makeSound() {81        System.out.println(name + " makes a sound");82    }83}8485class Dog extends Animal {86    Dog(String name) {87        super(name);88    }89    90    @Override91    void makeSound() {92        System.out.println(name + " barks!");93    }94    95    void fetch() {96        System.out.println(nameBuddy + " fetches the ball!");97    }
    outputBuddy fetches the ball!
  20. @Override void makeSound()

    58        for (Animal a : animals) {59            a.makeSound();  // Works for all60            61            // Type-specific behavior62            if (a instanceof Dog d) {63                d.fetch();64            } else if (a instanceof Cat c) {65                c.scratch();66            } else if (a instanceof Bird b) {67                b.fly();68            }69        }70    }71}7273class Animal {74    String name;75    76    Animal(String name) {77        this.name = name;78    }79    80    void makeSound() {81        System.out.println(name + " makes a sound");82    }83}8485class Dog extends Animal {86    Dog(String name) {87        super(name);88    }89    90    @Override91    void makeSound() {92        System.out.println(name + " barks!");93    }94    95    void fetch() {96        System.out.println(name + " fetches the ball!");97    }98}99100class Cat extends Animal {101    Cat(String name) {102        super(name);103    }104    105    @Override106    void makeSound() {107        System.out.println(nameWhiskers + " meows!");108    }
    outputWhiskers meows!
  21. @Override void makeSound()

    pass 2 of 2
    58        for (Animal a : animals) {59            a.makeSound();  // Works for all60            61            // Type-specific behavior62            if (a instanceof Dog d) {63                d.fetch();64            } else if (a instanceof Cat c) {65                c.scratch();66            } else if (a instanceof Bird b) {67                b.fly();68            }69        }70    }71}7273class Animal {74    String name;75    76    Animal(String name) {77        this.name = name;78    }79    80    void makeSound() {81        System.out.println(name + " makes a sound");82    }83}8485class Dog extends Animal {86    Dog(String name) {87        super(name);88    }89    90    @Override91    void makeSound() {92        System.out.println(nameMax + " barks!");93    }
    outputMax barks!
  22. void fetch()

    pass 2 of 2
    62            if (a instanceof Dog d) {63                d.fetch();64            } else if (a instanceof Cat c) {65                c.scratch();66            } else if (a instanceof Bird b) {67                b.fly();68            }69        }70    }71}7273class Animal {74    String name;75    76    Animal(String name) {77        this.name = name;78    }79    80    void makeSound() {81        System.out.println(name + " makes a sound");82    }83}8485class Dog extends Animal {86    Dog(String name) {87        super(name);88    }89    90    @Override91    void makeSound() {92        System.out.println(name + " barks!");93    }94    95    void fetch() {96        System.out.println(nameMax + " fetches the ball!");97    }
    outputMax fetches the ball!
  23. @Override void makeSound()

    58        for (Animal a : animals) {59            a.makeSound();  // Works for all60            61            // Type-specific behavior62            if (a instanceof Dog d) {63                d.fetch();64            } else if (a instanceof Cat c) {65                c.scratch();66            } else if (a instanceof Bird b) {67                b.fly();68            }69        }70    }71}7273class Animal {74    String name;75    76    Animal(String name) {77        this.name = name;78    }79    80    void makeSound() {81        System.out.println(name + " makes a sound");82    }83}8485class Dog extends Animal {86    Dog(String name) {87        super(name);88    }89    90    @Override91    void makeSound() {92        System.out.println(name + " barks!");93    }94    95    void fetch() {96        System.out.println(name + " fetches the ball!");97    }98}99100class Cat extends Animal {101    Cat(String name) {102        super(name);103    }104    105    @Override106    void makeSound() {107        System.out.println(name + " meows!");108    }109    110    void scratch() {111        System.out.println(name + " scratches!");112    }113}114115class Bird extends Animal {116    Bird(String name) {117        super(name);118    }119    120    @Override121    void makeSound() {122        System.out.println(nameTweety + " chirps!");123    }
    outputTweety chirps!
  24. void fly()

    66            } else if (a instanceof Bird b) {67                b.fly();68            }69        }70    }71}7273class Animal {74    String name;75    76    Animal(String name) {77        this.name = name;78    }79    80    void makeSound() {81        System.out.println(name + " makes a sound");82    }83}8485class Dog extends Animal {86    Dog(String name) {87        super(name);88    }89    90    @Override91    void makeSound() {92        System.out.println(name + " barks!");93    }94    95    void fetch() {96        System.out.println(name + " fetches the ball!");97    }98}99100class Cat extends Animal {101    Cat(String name) {102        super(name);103    }104    105    @Override106    void makeSound() {107        System.out.println(name + " meows!");108    }109    110    void scratch() {111        System.out.println(name + " scratches!");112    }113}114115class Bird extends Animal {116    Bird(String name) {117        super(name);118    }119    120    @Override121    void makeSound() {122        System.out.println(name + " chirps!");123    }124    125    void fly() {126        System.out.println(nameTweety + " flies away!");127    }
    outputTweety flies away!

if (animal instanceof Dog) checks real type before casting.

instanceof Check object's actual type: `obj instanceof Type`. Returns boolean.

Exercise: Practical.java

Build a payment processing system with polymorphism