Module 3: The Heart of Java

Object-Oriented Programming (Part 1): Classes and Objects.

Thinking in Objects

Welcome to Module 3! You've learned the basic syntax of Java, but now we dive into the paradigm that makes Java so powerful: **Object-Oriented Programming (OOP)**. Instead of just writing lists of instructions, OOP allows us to model real-world things. We can create a `Car` that has a color and can `drive()`, or a `User` that has a name and can `login()`. This approach makes our code more organized, reusable, and easier to understand.


1Classes vs. Objects: The Blueprint and the House

This is the most fundamental concept in OOP. It's best understood with an analogy:

  • A **Class** is a **blueprint**. A blueprint for a house defines what a house is: it has a number of bedrooms, a color, a front door, etc. The blueprint itself is not a house you can live in.
  • An **Object** is the **actual house** built from that blueprint. You can build many houses (objects) from the same blueprint. Each house can have different properties (e.g., one is blue with 3 bedrooms, another is white with 4 bedrooms), but they all share the same fundamental structure defined by the class.

Defining a Class

Let's create a blueprint for a `Dog`. A dog has a name, an age, and a breed. These are its properties, or **fields**. A dog can also perform actions, like barking. These actions are its **methods**. In IntelliJ, you'd create a new Java Class file named `Dog.java`.

public class Dog {
    // Fields (State or Properties)
    String name;
    int age;
    String breed;

    // Method (Behavior)
    void bark() {
        System.out.println("Woof Woof!");
    }
}

Creating Objects (Instances)

Now that we have the `Dog` blueprint, we can create actual dog objects from it in our `Main.java` file. This is called **instantiation**.

public class Main {
    public static void main(String[] args) {
        // Create a new Dog object from the Dog class
        Dog myDog = new Dog();

        // Set its properties (fields)
        myDog.name = "Buddy";
        myDog.age = 3;
        myDog.breed = "Golden Retriever";
        
        // Access and print the properties
        System.out.println(myDog.name + " is a " + myDog.breed);

        // Call its method
        myDog.bark(); // Outputs "Woof Woof!"
    }
}

2Constructors: The Initial Setup

Setting the fields for each object one by one is tedious. A **constructor** is a special method that gets called when an object is created (`new Dog()`). It's used to set the initial values for the object's fields.

A constructor has the same name as the class and no return type.

Creating a Constructor

Let's add a constructor to our `Dog` class to make creating dogs easier.

public class Dog {
    String name;
    int age;
    String breed;

    // Constructor
    public Dog(String dogName, int dogAge, String dogBreed) {
        name = dogName;
        age = dogAge;
        breed = dogBreed;
    }

    void bark() { ... }
}

Now, we can create fully-formed `Dog` objects in a single, clean line:

public static void main(String[] args) {
    // Create two different Dog objects using the constructor
    Dog dog1 = new Dog("Buddy", 3, "Golden Retriever");
    Dog dog2 = new Dog("Lucy", 5, "Poodle");

    System.out.println(dog1.name + " is " + dog1.age + " years old.");
    System.out.println(dog2.name + " is a " + dog2.breed);
}