# Classes and Objects

Course: [Java](https://www.devtutorials.ai/learn/java) · Section: Object-Oriented Programming
Source: https://www.devtutorials.ai/learn/java/object-oriented-programming/classes-and-objects

> Create your own types with classes, make objects with new, use fields, methods, this and constructors, control access with modifiers, and see objects on the stack and heap.

Think about a house plan drawn by an architect.

The plan shows where the rooms, doors and windows go. But you cannot live in a plan. A builder uses it to build real houses. One plan can produce many houses, and each house can have its own paint colour and its own family.

In Java, a class is the plan. An object is a real house built from it.

In simple words: a class describes what something has and what it can do, and an object is one real thing made from that description.

## What You Will Learn

In this lesson, you will learn:

1. What classes and objects are, and how they relate.
2. How to declare a class and create objects with `new`.
3. How object references work.
4. How to give a class fields and instance methods.
5. What the `this` keyword means.
6. How constructors set up a new object, including overloading and chaining.
7. How access modifiers control who can use a class's members.
8. Where objects and variables live in memory: the stack and the heap.

## Start With a Working Example

Press **Run**.

```java runnable title="One class, two separate objects"
public class Main {
    public static void main(String[] args) {
        Car first = new Car("Red", 2020);
        Car second = new Car("Blue", 2024);

        first.describe();
        second.describe();
    }
}

class Car {
    String colour;
    int year;

    Car(String colour, int year) {
        this.colour = colour;
        this.year = year;
    }

    void describe() {
        System.out.println("A " + colour + " car from " + year);
    }
}
```

Expected output:

```text
A Red car from 2020
A Blue car from 2024
```

`Car` is the class. `first` and `second` are two objects made from it. Each object keeps its own colour and year.

### Try This

Create a third car, `new Car("Green", 2018)`, and call `describe()` on it. You did not have to change the `Car` class at all.

## Introduction to Classes

So far, you have used built-in types like `int`, `String` and arrays. Real programs deal with things those types cannot describe on their own: a student, a bank account, an order.

A **class** lets you make your own type. It groups related data and actions under one name.

- The **data** are called **fields**. A student has a name and a roll number.
- The **actions** are called **methods**. A student can enrol in a course.

This style of programming is called **object-oriented programming (OOP)**. You build programs out of objects that each look after their own data.

## Classes and Objects

A **class** is a blueprint. It describes what every object of that type will have.

An **object** is one real thing made from the class. Making an object is called **instantiation**, and each object is an **instance** of its class.

| Class | Objects of that class |
|---|---|
| `Student` | Asha, Ravi, Meena |
| `Car` | your red car, my blue car |
| `BankAccount` | account 1001, account 1002 |

Think of a cookie cutter. The cutter is the class. Each cookie is an object. All the cookies have the same shape, but you can decorate each one differently.

## Class Declaration

You declare a class with the `class` keyword, a name, and a body in curly braces.

```text
class Student {
    // fields
    // constructors
    // methods
}
```

- Class names use **PascalCase**: `Student`, `BankAccount`, `OrderItem`.
- A file can hold many classes, but only one can be `public`, and its name must match the file name.

In this course, every runnable cell lives in a file called `Main.java`. So only `Main` is `public`. Other classes in the same cell, like `Car`, have no `public` keyword.

## Object Creation

You create an object in three steps, usually written on one line:

```text
Student s = new Student();
```

1. **Declare** a variable of the class type: `Student s`.
2. **Create** the object with `new Student()`.
3. **Assign** the new object to the variable with `=`.

After that, you use the dot `.` to reach the object's fields and methods: `s.name`, `s.enrol()`.

## new Keyword

The `new` keyword does three jobs:

1. It finds space in memory for the new object.
2. It runs the class's **constructor** to set the object up.
3. It returns a **reference** to the new object.

Every call to `new` makes a brand-new, separate object.

## Object References

A class-type variable does not hold the object itself. It holds a **reference**, which is like the address of the object in memory.

Think of a house address written on a card. The card is not the house. If you copy the card, both copies lead to the same house.

```java runnable title="Two references can point to the same object"
public class Main {
    public static void main(String[] args) {
        Account a = new Account();
        a.balance = 500;

        Account b = a;
        b.balance = 900;

        Account c = new Account();
        c.balance = 500;

        System.out.println("a: " + a.balance);
        System.out.println("b: " + b.balance);
        System.out.println("c: " + c.balance);
        System.out.println("a == b? " + (a == b));
        System.out.println("a == c? " + (a == c));
    }
}

class Account {
    int balance;
}
```

Expected output:

```text
a: 900
b: 900
c: 500
a == b? true
a == c? false
```

`Account b = a;` does not copy the object. It copies the reference. So `a` and `b` point to the **same** account, and changing `b.balance` also changes what `a` sees.

`c` was made with its own `new`, so it is a separate object.

A reference that points to no object holds `null`. Using a `null` reference, like `x.balance` when `x` is `null`, stops the program with a `NullPointerException`.

## Fields

A **field** is a variable that belongs to a class. Fields hold an object's data.

### Instance Fields

An **instance field** belongs to each object separately. Every object gets its own copy.

If you have 30 `Student` objects, there are 30 separate `name` fields, one in each object.

### Field Initialization

A field can get its starting value in three ways:

- **Default value.** If you give no value, Java uses `0`, `0.0`, `false` or `null`, depending on the type.
- **At the declaration.** `int lives = 3;` gives every new object 3 lives.
- **In a constructor.** The constructor sets values that differ from object to object.

```java runnable title="Default values and declared starting values"
public class Main {
    public static void main(String[] args) {
        Player p = new Player();

        System.out.println("name: " + p.name);
        System.out.println("score: " + p.score);
        System.out.println("isActive: " + p.isActive);
        System.out.println("lives: " + p.lives);
        System.out.println("level: " + p.level);
    }
}

class Player {
    String name;
    int score;
    boolean isActive;
    int lives = 3;
    String level = "Beginner";
}
```

Expected output:

```text
name: null
score: 0
isActive: false
lives: 3
level: Beginner
```

`name`, `score` and `isActive` were not given a value, so they hold the defaults. `lives` and `level` were given starting values in the class.

Fields get default values. Local variables inside a method do not. That is why Java complains when you use an uninitialized local variable, but not an uninitialized field.

Local variables inside a method do **not** get default values. Only fields do. That is why `int count; count++;` inside a method does not compile, while an `int count;` field simply starts at `0`.

## Instance Methods

An **instance method** is a method that belongs to an object. It has no `static` keyword, and it can read and change that object's fields.

You call it on an object: `cart.addItem(250)`.

```java runnable title="Methods change the object they are called on"
public class Main {
    public static void main(String[] args) {
        Cart mine = new Cart();
        Cart yours = new Cart();

        mine.addItem(250);
        mine.addItem(120);
        yours.addItem(999);

        mine.showTotal();
        yours.showTotal();
    }
}

class Cart {
    int total = 0;
    int items = 0;

    void addItem(int price) {
        total += price;
        items++;
    }

    void showTotal() {
        System.out.println(items + " item(s), total " + total);
    }
}
```

Expected output:

```text
2 item(s), total 370
1 item(s), total 999
```

`mine.addItem(250)` changes only `mine`. The `yours` cart keeps its own `total` and `items`.

## this Keyword

Inside a method or constructor, **`this`** means "the current object", the object the method was called on.

The most common use is to tell a field apart from a parameter with the same name.

```text
class Student {
    String name;

    Student(String name) {
        this.name = name;   // field = parameter
    }
}
```

`this.name` is the field. `name` on its own is the parameter.

Without `this`, `name = name;` would just copy the parameter into itself. The field would stay `null`.

```java runnable title="Without this, the field is never set"
public class Main {
    public static void main(String[] args) {
        WithThis good = new WithThis("Asha");
        WithoutThis bad = new WithoutThis("Asha");

        System.out.println("With this: " + good.name);
        System.out.println("Without this: " + bad.name);
    }
}

class WithThis {
    String name;
    WithThis(String name) {
        this.name = name;
    }
}

class WithoutThis {
    String name;
    WithoutThis(String name) {
        name = name;
    }
}
```

Expected output:

```text
With this: Asha
Without this: null
```

In `WithoutThis`, both sides of `name = name;` mean the parameter. The field was never touched.

## Constructors

A **constructor** is a special method that runs automatically when an object is created with `new`. Its job is to set up the new object.

A constructor:

- has **the same name as the class**;
- has **no return type**, not even `void`.

### Default Constructor

If you write no constructor at all, Java adds an empty one for you. This is the **default constructor**. It takes no parameters and leaves every field at its default or declared value.

That is why `new Player()` worked earlier, even though `Player` had no constructor.

Once you write **any** constructor yourself, Java stops adding the default one.

### Parameterized Constructor

A **parameterized constructor** takes values, so each object can start with different data.

### Constructor Overloading

A class can have several constructors, as long as their parameters differ. This is **constructor overloading**, just like method overloading.

### Constructor Chaining

One constructor can call another constructor of the same class with **`this(...)`**. This is **constructor chaining**.

It lets you keep the setup code in one constructor, and have the others pass their values to it.

`this(...)` must be the **first line** of the constructor.

```java runnable title="Three constructors, one place that does the work"
public class Main {
    public static void main(String[] args) {
        Book a = new Book();
        Book b = new Book("Wings of Fire");
        Book c = new Book("Malgudi Days", 250);

        a.show();
        b.show();
        c.show();
    }
}

class Book {
    String title;
    int price;

    Book() {
        this("Untitled");
    }

    Book(String title) {
        this(title, 100);
    }

    Book(String title, int price) {
        this.title = title;
        this.price = price;
        System.out.println("Created: " + title);
    }

    void show() {
        System.out.println(title + " costs " + price);
    }
}
```

Expected output:

```text
Created: Untitled
Created: Wings of Fire
Created: Malgudi Days
Untitled costs 100
Wings of Fire costs 100
Malgudi Days costs 250
```

`new Book()` calls the first constructor. It passes `"Untitled"` to the second one, which passes `100` to the third. Only the third constructor actually sets the fields.

So "Created" prints once per book, from one place.

| Constructor type | Parameters | Written by |
|---|---|---|
| Default constructor | None | Java, only if you write no constructor |
| No-argument constructor | None | You |
| Parameterized constructor | One or more | You |

## Object Initialization

When you write `new Book("Malgudi Days", 250)`, Java sets up the object in this order:

1. Memory is set aside, and every field gets its **default value** (`0`, `null`, `false`).
2. Fields with a **declared value**, like `int lives = 3;`, get that value.
3. The **constructor body** runs.
4. `new` returns a reference to the finished object.

So a constructor can always rely on declared field values already being in place.

```java runnable title="Declared values are set before the constructor runs"
public class Main {
    public static void main(String[] args) {
        Ticket t = new Ticket(4);
        System.out.println("Seats: " + t.seats + ", total: " + t.total);
    }
}

class Ticket {
    int pricePerSeat = 150;
    int seats;
    int total;

    Ticket(int seats) {
        System.out.println("Price already set to " + pricePerSeat);
        this.seats = seats;
        this.total = seats * pricePerSeat;
    }
}
```

Expected output:

```text
Price already set to 150
Seats: 4, total: 600
```

`pricePerSeat` was already `150` when the constructor started. So the constructor could use it to work out the total.

## Access Modifiers

An **access modifier** controls which other code can use a class, field, method or constructor.

Think of the rooms in a house. Anyone may enter the front garden. Only family members may enter the bedrooms. Some rooms are open to relatives, and some only to the people in that house.

### public

`public` means **any** code, anywhere, can use the member.

### private

`private` means only code **inside the same class** can use the member. This is the strictest level.

Fields are usually `private`, so other classes cannot change them directly.

### protected

`protected` means code in the **same package**, plus **child classes** in other packages, can use the member. You will see child classes in the Inheritance lesson.

### default

If you write **no** modifier, the member gets **default** access, also called **package-private**. Only code in the **same package** can use it.

A **package** is a folder of related classes, like `java.util`.

| Modifier | Same class | Same package | Child class elsewhere | Any other code |
|---|---|---|---|---|
| `public` | Yes | Yes | Yes | Yes |
| `protected` | Yes | Yes | Yes | No |
| default (none) | Yes | Yes | No | No |
| `private` | Yes | No | No | No |

```java runnable expect-error title="Another class cannot reach a private field"
public class Main {
    public static void main(String[] args) {
        Wallet w = new Wallet();
        w.cash = 1000000;
        System.out.println(w.cash);
    }
}

class Wallet {
    private int cash = 500;
}
```

The compiler reports `cash has private access in Wallet`. Only code inside `Wallet` can touch `cash`.

To let other code read or change a private field safely, the class adds public methods. You will learn this pattern in the Encapsulation lesson.

**Easy Way to Remember:** start with `private` for every field. Make something more open only when another class truly needs it.

## Memory View

When a Java program runs, the JVM uses two main areas of memory: the **stack** and the **heap**.

### Stack

The **stack** holds each method's **local variables** and parameters.

- Every method call gets its own small block, called a **frame**.
- When the method ends, its frame is removed, and its local variables disappear.
- Primitive local variables (`int`, `double` and so on) store their value right here.
- Reference variables store only the **address** of an object here.

### Heap

The **heap** holds every **object** created with `new`, together with its fields.

- Objects stay on the heap as long as some reference points to them.
- When no reference points to an object any more, the **garbage collector** frees its memory automatically.

```text
   STACK (main's frame)            HEAP
  ┌───────────────────┐
  │ int count = 2     │
  │ Car first  ───────┼──────►  ┌───────────────────┐
  │                   │         │ Car               │
  │ Car second ───────┼───┐     │ colour = "Red"    │
  └───────────────────┘   │     │ year   = 2020     │
                          │     └───────────────────┘
                          └──►  ┌───────────────────┐
                                │ Car               │
                                │ colour = "Blue"   │
                                │ year   = 2024     │
                                └───────────────────┘
```

`count` is a primitive, so its value, `2`, sits on the stack. `first` and `second` are references. The stack only holds their addresses. The `Car` objects themselves live on the heap.

| | Stack | Heap |
|---|---|---|
| Holds | Local variables and parameters | Objects and their fields |
| Created when | A method is called | `new` runs |
| Removed when | The method ends | No reference points to the object |
| Managed by | Method calls and returns | The garbage collector |

## Common mistakes

The following mistakes are common when writing classes, constructors and objects. Each row shows what you see, why it happens and how to fix it.

| Symptom | Cause | Fix |
|---|---|---|
| `cannot be applied to given types` on `new` | The constructor you call does not exist | Add a matching constructor |
| A field stays `null` or `0` after construction | `name = name;` without `this` | Write `this.name = name;` |
| `NullPointerException` | The reference was never given an object | Create the object with `new` first |
| `has private access` | Another class used a private member | Use a public method instead |
| `call to this must be first statement` | `this(...)` came after other code | Move it to the first line |
| Changing one object changes another | Both variables point to the same object | Create a second object with `new` |

## What to Remember

- A class is a blueprint. An object is one instance of it, created with `new`.
- A class-type variable holds a reference. Copying it shares the same object.
- Fields hold an object's data and get default values. Instance methods act on that object's fields.
- `this` means the current object. Use `this.field = parameter` when names match.
- Constructors have the class's name and no return type. They can be overloaded and chained with `this(...)`.
- `public`, `protected`, default and `private` control who can use each member. Make fields `private` by default.
- Local variables live on the stack. Objects live on the heap, and the garbage collector frees them.

Next: Static Members
