Index

Understanding Objects and Classes

Java for Beginners

4.1 Defining Classes and Creating Objects

In Java, everything revolves around objects. Objects represent real-world things or concepts by combining data and behavior. To create objects, you first need a class, which acts like a blueprint describing what an object should look like and what it can do.

In this section, we’ll learn how to define a class and create objects from it, covering key concepts like class structure, naming conventions, and the new keyword. We’ll also peek under the hood to see what happens during object creation.

What Is a Class?

A class is a template or blueprint that defines:

The class itself is not an object but a design for objects.

Basic Structure of a Java Class

Here’s a simple example of a class named Person:

public class Person {
    // Fields (attributes)
    String name;
    int age;

    // Method (behavior)
    void sayHello() {
        System.out.println("Hello! My name is " + name + ".");
    }
}

Explanation:

Naming Conventions

Creating Objects (Instantiating a Class)

To create an actual object from the class blueprint, you use the new keyword followed by the class constructor (which we’ll cover later but can be called simply by the class name and parentheses for now).

Example: Creating and Using a Person Object

public class PersonExample {
    public static void main(String[] args) {
        Person person1 = new Person(); // Create a new Person object

        // Assign values to fields
        person1.name = "Alice";
        person1.age = 30;

        // Call method on the object
        person1.sayHello();
    }
}

Output:

Hello! My name is Alice.
Click to view full runnable Code

class Person {
    // Fields (attributes)
    String name;
    int age;

    // Method (behavior)
    void sayHello() {
        System.out.println("Hello! My name is " + name + ".");
    }
}
public class Test {
    public static void main(String[] args) {
        Person person1 = new Person(); // Create a new Person object

        // Assign values to fields
        person1.name = "Alice";
        person1.age = 30;

        // Call method on the object
        person1.sayHello();
    }
}

Another Example: Defining and Creating a Car Object

class Car {
    String make;
    String model;
    int year;

    void displayInfo() {
        System.out.println(year + " " + make + " " + model);
    }
}

public class CarDemo {
    public static void main(String[] args) {
        Car myCar = new Car();
        myCar.make = "Toyota";
        myCar.model = "Camry";
        myCar.year = 2020;

        myCar.displayInfo();
    }
}

Output:

2020 Toyota Camry

What Happens When You Create an Object?

When you write:

Person person1 = new Person();
Person person2 = new Person();

person2 refers to a different object in memory.

Reference vs. Value

This is why:

Person person1 = new Person();
Person person2 = person1; // Both point to the same object!

Changing a field through person2 will affect the same object as person1.

Write Your Own Class and Create Objects

Try this:

Example skeleton:

class Book {
    // fields here

    // method here
}

public class BookDemo {
    public static void main(String[] args) {
        // create Book object and use it
    }
}
Index

4.2 Fields and Methods in Classes

In Java, classes combine both data and behavior to model real-world objects. The data is stored in fields (also called variables), and the behavior is defined by methods. This section explains how to declare fields and methods inside a class, and the difference between instance variables and class (static) variables.

Fields: Storing Data in a Class

Fields represent the properties or attributes of an object. When you create an object (an instance of a class), it can hold its own unique data in its instance variables.

Instance Variables

public class Student {
    String name;   // instance variable
    int grade;     // instance variable
}

Class (Static) Variables

public class Student {
    String name;
    int grade;
    static int studentCount; // static variable shared by all Students
}

Every time a new Student is created, you could increase studentCount to track the total number of students.

Methods: Defining Behavior

Methods are blocks of code that describe what objects can do or what operations can be performed on their data.

Method Structure

returnType methodName(parameterList) {
    // method body
}

Example: Book Class with Fields and Methods

public class Book {
    // Fields
    String title;
    String author;
    int pages;
    static int bookCount = 0; // counts all Book objects created

    // Constructor (to be covered later), for now assume default constructor

    // Method to display book info
    void displayInfo() {
        System.out.println(title + " by " + author + ", " + pages + " pages");
    }

    // Method to check if the book is a long read
    boolean isLongBook() {
        return pages > 300;
    }
}

public class BookDemo {
    public static void main(String[] args) {
        Book myBook = new Book(); // Create a new Book object

        // Set fields
        myBook.title = "Java Basics";
        myBook.author = "Jane Doe";
        myBook.pages = 350;

        // Call methods
        myBook.displayInfo();

        if (myBook.isLongBook()) {
            System.out.println("This is a long book.");
        } else {
            System.out.println("This book is short.");
        }
    }
}

Output:

Java Basics by Jane Doe, 350 pages
This is a long book.

Key Takeaways

Index

4.3 Constructors and this Keyword

When you create an object in Java, it’s important to initialize its fields — that is, set its initial state. This is where constructors come into play. Constructors are special methods designed to set up new objects right when they are created.

In this section, we will explore what constructors are, how they differ from regular methods, how to use the this keyword to distinguish between fields and parameters, and how constructors can be overloaded and chained.

What Is a Constructor?

A constructor is a special method that is automatically called when a new object is created using the new keyword. Its main purpose is to initialize the object’s fields.

How Constructors Differ from Regular Methods

Default Constructor

If you don’t provide any constructors in your class, Java automatically creates a default constructor with no parameters that does nothing but create the object.

public class Rectangle {
    int width;
    int height;
}

In this case, you can create objects like:

Rectangle rect = new Rectangle();

But the fields width and height remain uninitialized (default to 0).

Parameterized Constructor

To set fields with meaningful values at creation, you define a constructor that takes parameters:

public class Rectangle {
    int width;
    int height;

    // Parameterized constructor
    public Rectangle(int width, int height) {
        this.width = width;   // 'this' distinguishes field from parameter
        this.height = height;
    }
}

The this Keyword

In the constructor above, the keyword this refers to the current object. It helps differentiate between:

Without this, writing width = width; would just assign the parameter to itself and leave the field unchanged.

Constructor Overloading and Chaining

You can define multiple constructors with different parameter lists. This is constructor overloading.

Example: Overloaded Constructors with Chaining

public class Rectangle {
    int width;
    int height;

    // Default constructor
    public Rectangle() {
        this(10, 10);  // Calls the parameterized constructor with default values
    }

    // Parameterized constructor
    public Rectangle(int width, int height) {
        this.width = width;
        this.height = height;
    }
}

public class RectangleDemo {
    public static void main(String[] args) {
        Rectangle r1 = new Rectangle();        // Uses default constructor
        Rectangle r2 = new Rectangle(5, 8);    // Uses parameterized constructor

        System.out.println("Rectangle 1: " + r1.width + "x" + r1.height);
        System.out.println("Rectangle 2: " + r2.width + "x" + r2.height);
    }
}

Here:

Output:

Rectangle 1: 10x10  
Rectangle 2: 5x8

Practical Example 2: Constructor Overloading in a Person Class

public class Person {
    String name;
    int age;

    // Constructor with name only
    public Person(String name) {
        this(name, 0);  // Calls the other constructor, sets age to 0
    }

    // Constructor with name and age
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    void display() {
        System.out.println(name + ", Age: " + age);
    }
}

public class PersonDemo {
    public static void main(String[] args) {
        Person p1 = new Person("Alice");
        Person p2 = new Person("Bob", 25);

        p1.display();  // Output: Alice, Age: 0
        p2.display();  // Output: Bob, Age: 25
    }
}

Why Use Constructors?

Summary

Index

4.4 Introduction to Encapsulation

In object-oriented programming, encapsulation is one of the core principles that helps keep your code organized, secure, and easy to maintain. But what exactly is encapsulation, and why is it so important?

What Is Encapsulation?

Encapsulation means wrapping the data (fields) and the code that manipulates the data (methods) into a single unit — a class — and restricting direct access to some of the object’s components.

In simpler terms:

This is often described as data hiding and is essential for building reliable software.

Why Is Encapsulation Important?

How to Encapsulate Data in Java

Step 1: Make Fields private

This restricts direct access from outside the class.

public class Student {
    private String name;    // private field
    private int age;        // private field
}

Step 2: Provide Public Getter and Setter Methods

These allow controlled access and modification of the fields.

public class Student {
    private String name;
    private int age;

    // Getter for name
    public String getName() {
        return name;
    }

    // Setter for name
    public void setName(String name) {
        this.name = name;
    }

    // Getter for age
    public int getAge() {
        return age;
    }

    // Setter for age with validation
    public void setAge(int age) {
        if (age >= 0) {            // simple validation
            this.age = age;
        }
    }
}
// Example: Using Encapsulation

public class StudentDemo {
    public static void main(String[] args) {
        Student student = new Student();

        // Using setters to set values
        student.setName("John");
        student.setAge(20);

        // Using getters to retrieve values
        System.out.println("Name: " + student.getName());
        System.out.println("Age: " + student.getAge());

        // Attempt to set invalid age
        student.setAge(-5); // Age remains unchanged due to validation
        System.out.println("Updated Age: " + student.getAge());
    }
}

Output:

Name: John  
Age: 20  
Updated Age: 20

How Encapsulation Supports Maintainability and Reduces Complexity

Imagine if the Student class allowed direct access to the age field — any part of your program could set it to an invalid number (like -5), causing errors or inconsistencies.

By using private fields and setters with validation, you can:

This modular approach makes your code easier to understand, test, and modify.

Encouragement: Refactor Your Previous Classes

If you have written classes like Person, Book, or Car without encapsulation, try refactoring them:

Summary

By practicing encapsulation, you will write safer, clearer, and more professional Java code — a vital skill as your programs grow larger and more complex.

Index