Beginner Friendly ยท Java

Object-Oriented Programming
with Java

A fun, friendly, and hands-on course for young programmers โ€” no experience needed! ๐Ÿš€

โญ โญ โญ โญ โญ
๐Ÿ“š Your Progress
0%
Lesson 1 of 9

๐ŸŒŸ Welcome to Object-Oriented Programming!

Let's find out what OOP is, why it's super important, and why Java is such a great language to learn it with.

๐Ÿค” What Even Is Programming?

Imagine you want to teach a robot to make a sandwich. You'd have to give it step-by-step instructions: get bread, spread peanut butter, put them together. That's basically what programming is โ€” giving a computer precise instructions so it can do something useful.

But as the tasks get bigger (imagine a robot that runs an entire restaurant!), those instructions get very messy and hard to manage. That's where Object-Oriented Programming saves the day! ๐Ÿฆธ

๐ŸŽ Real World Analogy

Think about LEGO bricks. Each brick is a self-contained piece. You can snap them together, take them apart, reuse them, and build enormous things! OOP works the same way โ€” you build your program out of small, self-contained pieces called objects.

๐Ÿ’ก What Is OOP? (Object-Oriented Programming)

OOP is a way of writing programs where you organize your code around objects. An object is like a mini-robot that:

  • Knows certain things (its data/attributes) โ€” like a dog knows its name and breed
  • Can do certain things (its methods/behaviors) โ€” like a dog can bark, sit, or fetch

Instead of writing one giant list of instructions, you build a bunch of smart objects that work together. This makes your code:

  • โœ… Easier to understand
  • โœ… Easier to fix when something breaks
  • โœ… Easier to reuse in other projects
๐Ÿ”’

Encapsulation

Hiding private details, showing only what's needed

๐Ÿ‘ช

Inheritance

Children inherit traits from parents

๐ŸŽญ

Polymorphism

One action, many different forms

๐Ÿงฉ

Abstraction

Show the big picture, hide the complexity

โ˜• Why Java?

Java is one of the most popular programming languages in the world! Here's why it's perfect for learning OOP:

  • Pure OOP โ€” Java was built from the ground up with OOP in mind
  • Used everywhere โ€” Android apps, banking software, NASA, Minecraft (originally!) all use Java
  • Great error messages โ€” Java tells you clearly when you make a mistake
  • Free! โ€” You can download and use Java for free
Java โ€” Your Very First Program
// This is your first Java program!
// Don't worry about every word yet โ€” just read it like a story.

public class HelloWorld {

    public static void main(String[] args) {

        // This line prints a message to the screen
        System.out.println("Hello! I am learning Java OOP! ๐Ÿš€");
        System.out.println("This is going to be awesome!");

    }

}
๐Ÿ’ก
How to run Java code You can try Java instantly at replit.com or jdoodle.com โ€” no installation needed! Just type your code and hit Run.
๐Ÿง  Quick Check!
Which of the following is NOT one of the four pillars of OOP?
Lesson 2 of 9

๐Ÿ—๏ธ Classes and Objects

A class is the blueprint. An object is the real thing built from that blueprint. Let's build some objects!

๐ŸŽ Real World Analogy

Imagine a cookie cutter. The cutter is the class โ€” it's the template. Every cookie you stamp out is an object. All cookies have the same shape (from the same class), but you can decorate each one differently (each object has its own values)!

๐Ÿ“‹ What is a Class?

A class is a blueprint that describes what an object will look like and what it can do. A class contains:

  • Fields (attributes) โ€” the data the object holds (like a dog's name, age, breed)
  • Methods (behaviors) โ€” the actions the object can perform (like a dog can bark)
Java โ€” Creating a Class
// We're creating a blueprint for a Dog
public class Dog {

    // FIELDS โ€” these are the "facts" about a dog
    String name;
    String breed;
    int age;

    // METHOD โ€” this is something a dog can DO
    void bark() {
        System.out.println(name + " says: Woof! Woof! ๐Ÿ•");
    }

    void introduce() {
        System.out.println("Hi! I'm " + name +
            ", a " + age + "-year-old " + breed + "!");
    }

}
๐Ÿพ What is an Object?

An object is a real instance of a class. You use the keyword new to create one. Once you create an object, you can set its data and call its methods.

Java โ€” Creating Objects from the Dog Class
public class Main {

    public static void main(String[] args) {

        // Create a Dog object called "myDog"
        Dog myDog = new Dog();
        myDog.name  = "Buddy";
        myDog.breed = "Golden Retriever";
        myDog.age   = 3;

        // Create ANOTHER Dog object โ€” same blueprint, different dog!
        Dog friendsDog = new Dog();
        friendsDog.name  = "Luna";
        friendsDog.breed = "Poodle";
        friendsDog.age   = 5;

        // Call their methods!
        myDog.introduce();    // Hi! I'm Buddy, a 3-year-old Golden Retriever!
        myDog.bark();          // Buddy says: Woof! Woof! ๐Ÿ•

        friendsDog.introduce();  // Hi! I'm Luna, a 5-year-old Poodle!
        friendsDog.bark();       // Luna says: Woof! Woof! ๐Ÿ•

    }
}
๐Ÿ”‘
Key Rule: Class vs Object A class is a blueprint (written once). Objects are built FROM that blueprint (you can make as many as you want!). One Dog class โ†’ unlimited dog objects!
Follow-Along Challenge
๐ŸŽฏ Try It Yourself!

Build a Video Game Character Class

Create a class called GameCharacter with these fields:

  • String name
  • int health
  • int level
  • String weapon

Add a method showStats() that prints all the character's info. Then create 2 different character objects!

๐Ÿง  Quick Check!
You use the _____ keyword to create a new object from a class in Java.
Lesson 3 of 9

๐Ÿ”’ Encapsulation โ€” Keep Your Secrets Safe!

Encapsulation means bundling data and methods together, and controlling who can access or change that data. It's like putting your stuff in a locked box.

๐ŸŽ Real World Analogy

Think of an ATM machine. You can deposit money, check your balance, and withdraw cash โ€” those are the things the ATM lets you do. But you have NO idea (and no access to) how it works internally. All those complicated bank connections and security systems are hidden from you. That's encapsulation!

๐Ÿ” Access Modifiers

Java uses keywords called access modifiers to control who can see and change data:

ModifierWho can access it?
publicAnyone, from anywhere
privateOnly code INSIDE this class
protectedThis class + subclasses

The golden rule: make fields private and provide public methods to access them safely.

Java โ€” Encapsulation with Getters & Setters
public class BankAccount {

    // Private โ€” no one outside can touch this directly!
    private String ownerName;
    private double balance;

    // GETTER โ€” lets people READ the balance
    public double getBalance() {
        return balance;
    }

    // SETTER โ€” lets people ADD money, but with a safety check!
    public void deposit(double amount) {
        if (amount > 0) {
            balance += amount;
            System.out.println("โœ… Deposited $" + amount);
        } else {
            System.out.println("โŒ Invalid amount! Can't deposit negative money.");
        }
    }

    public void withdraw(double amount) {
        if (amount > balance) {
            System.out.println("โŒ Not enough money!");
        } else {
            balance -= amount;
            System.out.println("๐Ÿ’ธ Withdrew $" + amount);
        }
    }

    public String getOwnerName() { return ownerName; }
    public void setOwnerName(String name) { ownerName = name; }
}

public class Main {
    public static void main(String[] args) {
        BankAccount myAccount = new BankAccount();
        myAccount.setOwnerName("Alex");
        myAccount.deposit(100.0);   // โœ… Deposited $100.0
        myAccount.deposit(-50.0);  // โŒ Invalid amount!
        myAccount.withdraw(30.0);  // ๐Ÿ’ธ Withdrew $30.0
        System.out.println("Balance: $" + myAccount.getBalance()); // Balance: $70.0
    }
}
๐ŸŽฏ
Why is this so useful? Without encapsulation, someone could write myAccount.balance = -9999999 and break everything! With private + setters, you control how data changes. You add protection rules!
๐ŸŽฏ Try It Yourself!

Build a Student Grade Book

Create a Student class with private fields: name, grade (a number 0โ€“100). Write:

  • A getter getGrade()
  • A setter setGrade(int g) that only allows 0โ€“100
  • A method getLetterGrade() that returns "A", "B", "C", "D", or "F"
๐Ÿง  Quick Check!
Which access modifier makes a field only accessible inside its own class?
Lesson 4 of 9

๐Ÿ‘ช Inheritance โ€” Pass It Down!

Inheritance lets a new class reuse and build upon the code of an existing class, just like you inherit traits from your parents!

๐ŸŽ Real World Analogy

Think about animals. All animals eat and breathe. But a dog also barks and fetches. A cat also meows and purrs. So "Dog" and "Cat" inherit the basic animal traits and then add their own special ones. In Java, we say Dog and Cat extend Animal!

๐ŸŒณ The extends Keyword

When a class extends another class, it becomes its "child" or "subclass". The original class is called the "parent" or "superclass". The child automatically gets all the parent's fields and methods!

  • Superclass (parent) = the general blueprint
  • Subclass (child) = a more specific blueprint
  • The keyword super lets the child talk to the parent
Java โ€” Inheritance with Animals
// PARENT CLASS (Superclass)
public class Animal {
    protected String name;
    protected int age;

    public void eat() {
        System.out.println(name + " is eating. ๐Ÿ–");
    }

    public void sleep() {
        System.out.println(name + " is sleeping. ๐Ÿ’ค");
    }
}

// CHILD CLASS (Subclass) โ€” Dog inherits from Animal
public class Dog extends Animal {

    private String breed;

    // Dog's OWN special method
    public void bark() {
        System.out.println(name + " says: WOOF WOOF! ๐Ÿ•");
    }

    public void fetch() {
        System.out.println(name + " is fetching the ball! ๐ŸŽพ");
    }
}

// ANOTHER CHILD CLASS โ€” Cat also inherits from Animal
public class Cat extends Animal {

    public void meow() {
        System.out.println(name + " says: Meow~ ๐Ÿ˜บ");
    }

    public void purr() {
        System.out.println(name + " is purring... purrr ๐Ÿฑ");
    }
}

// Using it all together!
public class Main {
    public static void main(String[] args) {

        Dog dog = new Dog();
        dog.name = "Rex";
        dog.eat();    // Inherited from Animal! Rex is eating. ๐Ÿ–
        dog.bark();   // Dog's own method. Rex says: WOOF WOOF! ๐Ÿ•
        dog.fetch();  // Dog's own method. Rex is fetching the ball! ๐ŸŽพ

        Cat cat = new Cat();
        cat.name = "Whiskers";
        cat.sleep();  // Inherited from Animal! Whiskers is sleeping. ๐Ÿ’ค
        cat.meow();   // Cat's own method.
    }
}
โš ๏ธ
Java only allows ONE parent class In Java, a child class can only extend ONE parent. You can't write class Dog extends Animal, Pet. (But we can get around this with interfaces โ€” coming up in Lesson 8!)
๐Ÿ”„ Method Overriding

What if a child class wants to do the same thing as the parent, but differently? It can override the parent's method! You use the annotation @Override to make it clear.

Java โ€” Method Overriding
public class Animal {
    public void makeSound() {
        System.out.println("Some generic animal sound...");
    }
}

public class Dog extends Animal {
    // Override means "replace the parent's version"
    @Override
    public void makeSound() {
        System.out.println("Woof woof! ๐Ÿ•");
    }
}

public class Cat extends Animal {
    @Override
    public void makeSound() {
        System.out.println("Meow meow! ๐Ÿ˜บ");
    }
}
๐ŸŽฏ Try It Yourself!

Build a Video Game with Inheritance

Create a Character parent class with fields: name, health, level, and a method attack(). Then create two subclasses: Warrior (uses a sword โš”๏ธ) and Mage (uses magic โœจ). Override attack() in each to print a different message!

๐Ÿง  Quick Check!
Which keyword is used to make one class inherit from another in Java?
Lesson 5 of 9

๐ŸŽญ Polymorphism โ€” Many Forms!

Polymorphism means "many forms." The same method name can behave differently depending on which object calls it. It's one of OOP's superpowers!

๐ŸŽ Real World Analogy

Think about the word "speak". If you tell a human to speak, they talk. If you tell a dog to speak, it barks. If you tell a parrot to speak, it squawks. Same command โ€” totally different results! That's polymorphism.

๐ŸŽช Two Types of Polymorphism
TypeWhen it happensAlso called
Compile-timeMethod overloading โ€” same name, different parametersStatic polymorphism
RuntimeMethod overriding โ€” child replaces parent methodDynamic polymorphism
Java โ€” Polymorphism in Action
// Same method name, different behavior per object!
public class Animal {
    protected String name;
    public void makeSound() {
        System.out.println("...");
    }
}

class Dog extends Animal {
    @Override public void makeSound() {
        System.out.println(name + ": WOOF! ๐Ÿ•");
    }
}
class Cat extends Animal {
    @Override public void makeSound() {
        System.out.println(name + ": Meow! ๐Ÿ˜บ");
    }
}
class Duck extends Animal {
    @Override public void makeSound() {
        System.out.println(name + ": Quack! ๐Ÿฆ†");
    }
}

public class Main {
    public static void main(String[] args) {

        // An ARRAY of Animals โ€” but some are Dogs, Cats, Ducks!
        Animal[] animals = new Animal[3];

        Dog d = new Dog(); d.name = "Rex";
        Cat c = new Cat(); c.name = "Luna";
        Duck k = new Duck(); k.name = "Donald";

        animals[0] = d;
        animals[1] = c;
        animals[2] = k;

        // One loop โ€” each animal makes ITS OWN sound! ๐ŸŽ‰
        for (Animal a : animals) {
            a.makeSound();
        }
        // Output:
        // Rex: WOOF! ๐Ÿ•
        // Luna: Meow! ๐Ÿ˜บ
        // Donald: Quack! ๐Ÿฆ†
    }
}
โœจ
Why is this powerful? You can write ONE loop that works for ALL animals โ€” even animal types you haven't invented yet! When you add a Cow class with its own makeSound(), the loop automatically handles it. No changes needed!
Java โ€” Method Overloading (Compile-Time Polymorphism)
// Same method name, different parameters = overloading!
public class Calculator {

    // Add two integers
    public int add(int a, int b) {
        return a + b;
    }

    // Add three integers (same name!)
    public int add(int a, int b, int c) {
        return a + b + c;
    }

    // Add two doubles (same name!)
    public double add(double a, double b) {
        return a + b;
    }
}
// Java figures out WHICH version to call automatically!
๐ŸŽฏ Try It Yourself!

Create a Shape Drawing App

Create a Shape class with a method draw(). Create 3 subclasses: Circle, Square, and Triangle. Each overrides draw() to print something like "Drawing a circle โญ•". Then store them all in a Shape[] array and loop through, calling draw() on each!

๐Ÿง  Quick Check!
What does "polymorphism" literally mean?
Lesson 6 of 9

๐Ÿงฉ Abstraction โ€” Show the Big Picture!

Abstraction means hiding complex details and showing only the essential features. It helps you focus on WHAT something does instead of HOW it does it.

๐ŸŽ Real World Analogy

When you drive a car (or watch someone drive), you press the gas pedal to go faster. You don't need to know how the engine, fuel injectors, and crankshaft all work together internally. The car abstracts all that complexity away and gives you a simple interface: steering wheel, gas, brake. That's abstraction!

๐Ÿ”ต Abstract Classes

An abstract class is a class that can't be used to create objects directly โ€” it's just a template! It can have abstract methods (no body) that subclasses must implement.

  • Use keyword abstract before class
  • Abstract methods have no body โ€” just a declaration
  • Subclasses MUST provide implementations for all abstract methods
  • You can still have regular methods in abstract classes
Java โ€” Abstract Classes
// Abstract class โ€” can't be used to create an object directly!
public abstract class Vehicle {

    protected String brand;
    protected int speed;

    // Abstract method โ€” subclasses MUST implement this
    public abstract void move();
    public abstract void fuelUp();

    // Regular method โ€” already complete!
    public void showInfo() {
        System.out.println("Brand: " + brand + " | Speed: " + speed + "km/h");
    }
}

// Car implements the abstract methods
public class Car extends Vehicle {

    @Override
    public void move() {
        System.out.println(brand + " car is driving on the road! ๐Ÿš—");
    }

    @Override
    public void fuelUp() {
        System.out.println("Filling up with gasoline โ›ฝ");
    }
}

// Boat implements the abstract methods differently
public class Boat extends Vehicle {

    @Override
    public void move() {
        System.out.println(brand + " boat is sailing on water! โ›ต");
    }

    @Override
    public void fuelUp() {
        System.out.println("Filling up with marine diesel ๐Ÿ›ข๏ธ");
    }
}

public class Main {
    public static void main(String[] args) {
        Car car = new Car();
        car.brand = "Toyota";
        car.speed = 120;
        car.showInfo();  // Brand: Toyota | Speed: 120km/h
        car.move();      // Toyota car is driving on the road! ๐Ÿš—
        car.fuelUp();    // Filling up with gasoline โ›ฝ
    }
}
๐Ÿ“Œ
Abstract vs Regular Class You CANNOT do: Vehicle v = new Vehicle(); โ€” Java will give you an error! Abstract classes are templates only. You CAN do: Vehicle v = new Car(); โ€” using a Car object stored as a Vehicle type.
๐ŸŽฏ Try It Yourself!

Build an Abstract Phone System

Create an abstract class Phone with fields brand and model, and abstract methods call(String number) and chargeBattery(). Then create two classes: Smartphone and FlipPhone. Each implements the methods differently!

๐Ÿง  Quick Check!
Can you create an object directly from an abstract class?
Lesson 7 of 9

๐Ÿ”ง Constructors โ€” The Birth of an Object!

A constructor is a special method that runs automatically when you create an object. It's how you "set up" an object with its starting data right from birth!

๐ŸŽ Real World Analogy

When a baby is born, they already have some things set: a name, a birth date, eye color. The constructor is like the "birth certificate" โ€” it's filled out the moment the object is created, giving it its starting values right away!

๐Ÿ“ฆ What Is a Constructor?
  • It has the same name as the class
  • It has no return type (not even void)
  • It runs automatically when you write new ClassName()
  • You can have multiple constructors with different parameters (overloading!)
Java โ€” Constructors
public class Student {

    private String name;
    private int grade;
    private String school;

    // Constructor #1 โ€” no parameters (default)
    public Student() {
        name   = "Unknown";
        grade  = 0;
        school = "Unknown School";
        System.out.println("A new student was created (no info)!");
    }

    // Constructor #2 โ€” provide name and grade
    public Student(String studentName, int studentGrade) {
        name  = studentName;
        grade = studentGrade;
        school = "Default School";
        System.out.println("Student created: " + name);
    }

    // Constructor #3 โ€” full details
    public Student(String studentName, int studentGrade, String schoolName) {
        name   = studentName;
        grade  = studentGrade;
        school = schoolName;
        System.out.println("Student created: " + name + " at " + school);
    }

    public void introduce() {
        System.out.println("Hi! I'm " + name +
            ", Grade " + grade + " at " + school);
    }
}

public class Main {
    public static void main(String[] args) {

        // Uses Constructor #1
        Student s1 = new Student();
        s1.introduce();

        // Uses Constructor #2
        Student s2 = new Student("Alex", 7);
        s2.introduce();

        // Uses Constructor #3
        Student s3 = new Student("Maria", 8, "Oakwood Academy");
        s3.introduce();
    }
}
๐Ÿ”‘
The this keyword Inside a constructor (or method), this refers to the current object. If your parameter has the same name as a field, use this.name = name to be clear โ€” "this object's name = the parameter called name."
Java โ€” Using 'this' keyword
public class Pizza {
    private String size;
    private String topping;

    // "this.size" = the field, "size" = the parameter
    public Pizza(String size, String topping) {
        this.size    = size;
        this.topping = topping;
    }

    public void describe() {
        System.out.println("A " + size + " pizza with " + topping + "! ๐Ÿ•");
    }
}
๐ŸŽฏ Try It Yourself!

Build a Book Library System

Create a Book class with a constructor that takes title, author, and pages. Add a second constructor that only takes title and author (default pages = 100). Add a method describe(). Create 3 book objects using different constructors!

๐Ÿง  Quick Check!
What is special about a constructor's name?
Lesson 8 of 9

๐Ÿงฒ Interfaces โ€” Signing a Contract!

An interface is like a contract that a class agrees to follow. It lists the methods a class MUST have, without saying how to do them. This solves the "one parent only" limitation!

๐ŸŽ Real World Analogy

Think about a USB port. Any device that has a USB connector agrees to the "USB contract" โ€” specific size, specific pins. A phone, a keyboard, a mouse โ€” they're all totally different, but they all follow the same USB interface. In Java, classes that implement an interface agree to provide certain methods.

๐Ÿ“‹ Interface vs Abstract Class
InterfaceAbstract Class
Can have fields?Only constantsYes
Methods with body?Default methods onlyYes
A class can use how many?Multiple!Only one
Keywordimplementsextends
Java โ€” Interfaces in Action
// An interface โ€” defines a "contract"
public interface Swimmable {
    void swim();  // Any class that implements this MUST have swim()
}

public interface Flyable {
    void fly();
}

public interface Talkable {
    void talk();
}

// Duck can swim AND fly โ€” implements TWO interfaces!
public class Duck implements Swimmable, Flyable {

    private String name;

    public Duck(String name) { this.name = name; }

    @Override
    public void swim() {
        System.out.println(name + " is swimming! ๐ŸŠ");
    }

    @Override
    public void fly() {
        System.out.println(name + " is flying! ๐Ÿฆ†");
    }
}

// Parrot can fly AND talk!
public class Parrot implements Flyable, Talkable {

    private String name;
    public Parrot(String name) { this.name = name; }

    @Override
    public void fly() {
        System.out.println(name + " is flying! ๐Ÿฆœ");
    }

    @Override
    public void talk() {
        System.out.println(name + ": Polly wants a cracker! ๐Ÿฆœ");
    }
}

public class Main {
    public static void main(String[] args) {
        Duck duck = new Duck("Donald");
        duck.swim();  // Donald is swimming! ๐ŸŠ
        duck.fly();   // Donald is flying! ๐Ÿฆ†

        Parrot parrot = new Parrot("Polly");
        parrot.fly();  // Polly is flying! ๐Ÿฆœ
        parrot.talk(); // Polly: Polly wants a cracker! ๐Ÿฆœ
    }
}
๐ŸŽฏ
Superpower: Multiple Interfaces! A class can only extend ONE parent class. But it can implement as many interfaces as you want! This gives Java flexibility without the complications of multiple inheritance.
๐ŸŽฏ Try It Yourself!

Design a Superhero System

Create interfaces: Flyable, SuperStrong, Invisible. Then create superheroes: Superman (Flyable + SuperStrong), Invisible Woman (Invisible + SuperStrong), Iron Man (Flyable only, but flies with a suit!). Make each implement the interfaces their way!

๐Ÿง  Quick Check!
Which keyword does a class use when it wants to use an interface?
Lesson 9 of 9 โ€” Final Project! ๐Ÿ†

๐Ÿ† Build a Zoo Management System!

Bring EVERYTHING you've learned together! You'll build a complete Zoo app using all 4 pillars of OOP plus constructors and interfaces.

๐ŸŽ‰
You've come so far! You've learned Classes & Objects, Encapsulation, Inheritance, Polymorphism, Abstraction, Constructors, and Interfaces. Now let's use them ALL together to build something amazing!
๐Ÿ“‹ Project Plan
  • ๐Ÿงฉ Abstract class: Animal with abstract methods makeSound() and feed()
  • ๐Ÿงฒ Interfaces: Swimmable, Flyable, Trainable
  • ๐Ÿ‘ช Subclasses: Lion, Penguin, Eagle, Dolphin
  • ๐Ÿ”’ Encapsulation: Private fields with getters/setters
  • ๐Ÿ”ง Constructors: Each animal built with name + age
  • ๐ŸŽญ Polymorphism: One loop that calls makeSound() on all animals
Java โ€” Zoo Management System (Complete!)
// ============================================
// INTERFACES
// ============================================
interface Swimmable {
    void swim();
}
interface Flyable {
    void fly();
}
interface Trainable {
    void performTrick(String trick);
}

// ============================================
// ABSTRACT CLASS โ€” the base for all animals
// ============================================
abstract class Animal {
    private String name;
    private int age;
    private double weight;

    // Constructor
    public Animal(String name, int age, double weight) {
        this.name   = name;
        this.age    = age;
        this.weight = weight;
    }

    // Getters (Encapsulation!)
    public String getName()   { return name;   }
    public int    getAge()    { return age;    }
    public double getWeight() { return weight; }

    // Regular method โ€” shared by all animals
    public void displayInfo() {
        System.out.println("๐Ÿฆฎ Name: " + name +
            " | Age: " + age + "yrs | Weight: " + weight + "kg");
    }

    // Abstract methods โ€” each subclass defines these!
    public abstract void makeSound();
    public abstract void feed();
}

// ============================================
// SUBCLASSES
// ============================================
class Lion extends Animal implements Trainable {
    public Lion(String n, int a, double w) { super(n, a, w); }

    @Override public void makeSound() {
        System.out.println(getName() + ": ROAARRR! ๐Ÿฆ");
    }
    @Override public void feed() {
        System.out.println(getName() + " gets 10kg of fresh meat. ๐Ÿฅฉ");
    }
    @Override public void performTrick(String trick) {
        System.out.println(getName() + " performs: " + trick + " ๐ŸŽช");
    }
}

class Penguin extends Animal implements Swimmable, Trainable {
    public Penguin(String n, int a, double w) { super(n, a, w); }

    @Override public void makeSound() {
        System.out.println(getName() + ": Squawk squawk! ๐Ÿง");
    }
    @Override public void feed() {
        System.out.println(getName() + " gets a bucket of fish! ๐ŸŸ");
    }
    @Override public void swim() {
        System.out.println(getName() + " dives and swims gracefully! ๐ŸŠ");
    }
    @Override public void performTrick(String trick) {
        System.out.println(getName() + " waddles and does: " + trick);
    }
}

class Eagle extends Animal implements Flyable {
    public Eagle(String n, int a, double w) { super(n, a, w); }

    @Override public void makeSound() {
        System.out.println(getName() + ": Screech! ๐Ÿฆ…");
    }
    @Override public void feed() {
        System.out.println(getName() + " catches a fish from the pond! ๐Ÿ ");
    }
    @Override public void fly() {
        System.out.println(getName() + " soars high above the clouds! โ˜๏ธ");
    }
}

// ============================================
// MAIN โ€” the Zoo opens!
// ============================================
public class Zoo {
    public static void main(String[] args) {

        // Create our animals using constructors
        Animal[] animals = {
            new Lion("Simba", 5, 190.0),
            new Penguin("Pingu", 3, 5.0),
            new Eagle("Baldy", 7, 6.5)
        };

        System.out.println("=== ๐Ÿฆ Welcome to OOP Zoo! ๐Ÿฆ ===");

        // Polymorphism โ€” one loop, each animal acts differently!
        for (Animal a : animals) {
            a.displayInfo();
            a.makeSound();
            a.feed();
            System.out.println("---");
        }

        // Use interfaces specifically
        System.out.println("\n=== ๐ŸŽช Special Shows ===");
        Penguin p = (Penguin) animals[1];
        p.swim();
        p.performTrick("slide on ice");

        Eagle e = (Eagle) animals[2];
        e.fly();
    }
}
๐Ÿ†
Congratulations! Look what you used: โœ… Abstract class (Animal) ยท โœ… Interfaces (Swimmable, Flyable, Trainable) ยท โœ… Inheritance (extends Animal) ยท โœ… Polymorphism (one loop, many sounds) ยท โœ… Encapsulation (private + getters) ยท โœ… Constructors (name, age, weight) ยท โœ… Method Overriding (@Override)
๐Ÿš€ What to Build Next?

Now that you know OOP, here are awesome projects to try:

  • ๐ŸŽฎ A text-based RPG game with Warriors, Mages, and Rogues
  • ๐Ÿฆ A bank system with Checking and Savings accounts
  • ๐Ÿ›’ A simple shopping cart with Products and Discounts
  • ๐Ÿซ A school management system with Students and Teachers
  • ๐Ÿš€ A space exploration game with Planets and Spaceships
๐Ÿ† Final Quiz!
Which OOP concept means "hiding complexity and showing only what's needed"?
Roadmap