Java Polymorphism, Overloading, Lambdas & Exceptions

Constructor and Method Overloading

class Calculator {
    // Constructor overloading: same name, different parameters
    Calculator() { System.out.println("Default Calculator created"); }
    Calculator(String mode) { System.out.println(mode + " Calculator created"); }
    // Method overloading: same name, different parameters
    int add(int a, int b) { return a + b; }
    double add(double a, double b) { return a + b; }
}

public class OverloadingDemo {
    public static void main(String[] args) {
        Calculator c1 = new Calculator();
        Calculator c2 = new Calculator("Scientific");
        System.out.println("Int Sum: " + c1.add(5, 10));
        System.out.println("Double Sum: " + c1.add(5.5, 10.5));
    }
}

Polymorphism and Method Overriding

// Parent class
class Animal {
    void sound() {
        System.out.println("Animal makes a sound");
    }
}

// Child class
class Dog extends Animal {
    // Method overriding: same method signature as parent
    @Override
    void sound() {
        super.sound(); // Calls parent's sound()
        System.out.println("Dog barks: Bow Wow");
    }
}

public class PolymorphismDemo {
    public static void main(String[] args) {
        Animal a = new Dog(); // Runtime polymorphism
        a.sound(); // Output: Animal makes a sound
                   //         Dog barks: Bow Wow
        System.out.println(a instanceof Dog); // true
    }
}

Functional Interface and Lambda (Example 1)

// Functional interface (only one abstract method)
@FunctionalInterface
interface Drawable {
    void draw(String shape);
}

class ShapeDrawer implements Drawable {
    @Override
    public void draw(String shape) {
        System.out.println("Drawing a " + shape + " using Class");
    }
}

public class LambdaDemo {
    public static void main(String[] args) {
        // 1. Using a regular class
        Drawable d1 = new ShapeDrawer();
        d1.draw("Circle");
        // 2. Using lambda expression (most important)
        Drawable d2 = (s) -> System.out.println("Drawing a " + s + " using Lambda");
        d2.draw("Square");
    }
}

Functional Interface and Lambda (Duplicate Example)

// Functional interface (only one abstract method)
@FunctionalInterface
interface Drawable {
    void draw(String shape);
}

class ShapeDrawer implements Drawable {
    @Override
    public void draw(String shape) {
        System.out.println("Drawing a " + shape + " using Class");
    }
}

public class LambdaDemo {
    public static void main(String[] args) {
        // 1. Using a regular class
        Drawable d1 = new ShapeDrawer();
        d1.draw("Circle");
        // 2. Using lambda expression (most important)
        Drawable d2 = (s) -> System.out.println("Drawing a " + s + " using Lambda");
        d2.draw("Square");
    }
}

Exception Handling Examples

import java.io.FileWriter;
import java.io.IOException;

public class ExceptionDemo {
    public static void main(String[] args) {
        // Simple try-catch
        try {
            int result = 100 / 0; // ArithmeticException
        } catch (ArithmeticException e) {
            System.out.println("Error: Cannot divide by zero. " + e.getMessage());
        }
        // try-with-resources (example of file handling)
        // Automatically closes the resource (fw)
        try (FileWriter fw = new FileWriter("output.txt")) {
            fw.write("Java Exam Prep Data");
            System.out.println("Data written to file.");
        } catch (IOException e) {
            System.out.println("File Error: " + e.getMessage());
        }
    }
}