Java Tutorial » Chapter 4 — Objects & Classes

Chapter 4 — Java Objects & Classes

Understand the core of Object-Oriented Programming (OOP) in Java.

1. Objects in Java

What is an Object?

An object is a fundamental building block of Java. Think of it as a real-world entity. If you look around, you'll find many objects around you: a car, a dog, a desk.

These objects have two main characteristics:

  • State: The data or properties of an object (e.g., a car's color is red, its model is "Toyota").
  • Behavior: The actions an object can perform (e.g., a car can drive, a dog can bark).

In Java, an object is an instance of a class. It's the actual entity that exists in memory, with its own state and the ability to perform behaviors defined by its class.

2. Classes in Java

What is a Class?

A class is a blueprint or template for creating objects. It defines a set of properties (variables) and behaviors (methods) that every object created from it will have.

If an object is a specific car (like *your* red Toyota), then the class is the general design for all cars.

public class Car {
    // State (variables or fields)
    String color;
    String model;
    int year;

    // Behavior (methods)
    void drive() {
        System.out.println("The car is moving.");
    }

    void brake() {
        System.out.println("The car has stopped.");
    }
}

In this example, Car is the class. It defines that any car will have a color, model, and year, and it can drive() and brake().

3. Constructors

Initializing Objects

A constructor is a special method inside a class that is called when you create a new object. Its main job is to initialize the object's variables (its state).

Key Rules for Constructors:

  • The name of the constructor must be exactly the same as the class name.
  • It does not have a return type (not even void).

If you don't write a constructor, Java provides a default one that does nothing. But it's common to create your own to set initial values.

public class Car {
    String color;
    String model;

    // This is a constructor for the Car class
    public Car(String carColor, String carModel) {
        color = carColor; // Initialize the 'color' field
        model = carModel; // Initialize the 'model' field
        System.out.println("A new " + color + " " + model + " has been created.");
    }
    
    // ... other methods like drive() ...
}
4. Singleton Class

Ensuring Only One Instance

A Singleton is a special design pattern that restricts a class to creating only one single object. This is useful when you need exactly one object to coordinate actions across the system, like a database connection or a logging service.

How to Create a Singleton Class:

  1. Make the constructor private to prevent other classes from creating a new instance.
  2. Create a private static variable of the class's own type. This will hold the single instance.
  3. Create a public static method (commonly named getInstance()) that returns the single instance. It creates the instance on the first call and returns it on subsequent calls.
public class DatabaseConnection {
        // 2. The single, static instance
        private static DatabaseConnection instance;

        // 1. Private constructor to prevent instantiation
        private DatabaseConnection() {
            // Initialization code, e.g., connecting to the database
        }

        // 3. Public static method to get the instance
        public static DatabaseConnection getInstance() {
            if (instance == null) {
                // Create the instance only if it doesn't exist yet
                instance = new DatabaseConnection();
            }
            return instance;
        }
}
5. Creating an Object

Bringing Objects to Life

Creating an object from a class is called instantiation. You do this using the new keyword. The process involves three steps:

  1. Declaration: Declare a variable of the class type. Car myCar;
  2. Instantiation: Use the new keyword to create the object. new Car(...)
  3. Initialization: Call the constructor to initialize the object. Car("Red", "Toyota")

Usually, you do all three in one line:

public class Main {
    public static void main(String[] args) {
        // Creating an object (instantiation) of the Car class
        Car myToyota = new Car("Red", "Toyota");
        Car myFord = new Car("Blue", "Ford");

        // Now 'myToyota' and 'myFord' are two distinct objects
    }
}
6. Accessing Members

Working with Your Object

Once you have created an object, you can access its variables (state) and methods (behavior) using the dot operator (.).

  • To access an instance variable: objectName.variableName
  • To call an instance method: objectName.methodName()
public class Main {
    public static void main(String[] args) {
        Car myCar = new Car("Red", "Toyota");

        // Accessing instance variables
        System.out.println("Car color: " + myCar.color); // Outputs: Red
        System.out.println("Car model: " + myCar.model); // Outputs: Toyota

        // Modifying an instance variable
        myCar.color = "Black";
        System.out.println("New car color: " + myCar.color); // Outputs: Black

        // Calling an instance method
        myCar.drive(); // Outputs: The car is moving.
        myCar.brake(); // Outputs: The car has stopped.
    }
}

Note: It's good practice to make variables private and provide public methods (getters and setters) to access them. This is called encapsulation.

7. Source File Rules

Declaration Rules for Java Files

When writing Java code, you must follow these rules for your source files (.java files):

  • There can be only one public class per source file.
  • The source file name must exactly match the name of the public class. For example, if the public class is Car, the file must be saved as Car.java.
  • If the source file does not contain a public class, the file name can be anything (but it's good practice to name it after a class inside).
  • A source file can contain multiple non-public classes.
  • package statements must be at the very beginning of the file.
  • import statements must come after the package statement and before the class declaration.
8. Java Package

Organizing Your Classes

A package in Java is a mechanism for organizing related classes and interfaces. Think of it like a folder on your computer. It helps to:

  • Avoid naming conflicts: You can have a class named Student in a university package and another Student in a school package without any issues.
  • Provide access control: Packages help in controlling access to classes and members.

The package statement must be the first line in a source file.

// This file, Car.java, is part of the 'vehicles' package
package vehicles;

public class Car {
    // ... class body
}
9. Import Statements

Using Code from Other Packages

If you want to use a class from another package in your code, you need to import it. The import statement tells the Java compiler where to find the class you want to use.

For example, if you want to use the ArrayList class, which is in the java.util package, you must import it.

import java.util.ArrayList; // Import the ArrayList class

public class MyClass {
    public static void main(String[] args) {
        // Now you can use ArrayList without writing the full package name
        ArrayList names = new ArrayList<>();
        names.add("Alice");
        names.add("Bob");
        System.out.println(names);
    }
}

If you don't use an import, you would have to write the full name everywhere: java.util.ArrayList names = new java.util.ArrayList<>();

10. Simple Case Study

Putting It All Together: A Student Management System

Let's create a simple `Student` class and then use it in a `main` method to see how all these concepts work together.

Step 1: Create the `Student` Class Blueprint

This class will define what every student object will look like.

package university;

public class Student {
    // 1. Instance Variables (State)
    private String studentId;
    private String name;
    private double gpa;

    // 2. Constructor (for Initialization)
    public Student(String id, String studentName) {
        this.studentId = id;
        this.name = studentName;
        this.gpa = 0.0; // Default GPA
    }

    // 3. Methods (Behavior)
    public void setGpa(double newGpa) {
        if (newGpa >= 0.0 && newGpa <= 4.0) {
            this.gpa = newGpa;
        } else {
            System.out.println("Invalid GPA value.");
        }
    }

    public void displayStudentInfo() {
        System.out.println("Student ID: " + this.studentId);
        System.out.println("Student Name: " + this.name);
        System.out.println("Student GPA: " + this.gpa);
    }
}

Step 2: Use the `Student` Class in a Main Program

Now, let's create a `Main` class to create and interact with `Student` objects.

import university.Student; // 8. Import the Student class

public class Main {
    public static void main(String[] args) {
        // 5. Create two Student objects (instantiation)
        Student student1 = new Student("S101", "Alice");
        Student student2 = new Student("S102", "Bob");

        // 6. Access and modify object state using methods
        student1.setGpa(3.8);
        student2.setGpa(3.5);

        // 6. Call methods on the objects
        System.out.println("--- Information for Student 1 ---");
        student1.displayStudentInfo();

        System.out.println("\n--- Information for Student 2 ---");
        student2.displayStudentInfo();
    }
}

This example combines classes, objects, constructors, instance variables, methods, packages, and import statements into one complete program.