# Classes and Objects in Java — Constructors, this, static and Encapsulation

Source: https://skills101.in/learn/java/java-classes-and-objects — Skills101 free tutorial (Java Programming). Updated 2026-11-09.

A **class** is a blueprint; an **object** is a real thing built from it. Java programs are made of classes that work together.

![Stack vs heap: the variable s on the stack holds a reference to a Student object on the heap](https://skills101.in/learn-img/java/stack-heap.svg)

## 1. A class with fields, a constructor and methods

```java
class Student {
    String name;        // fields (instance variables)
    int marks;

    Student(String name, int marks) {   // constructor
        this.name = name;               // this.name = the field
        this.marks = marks;
    }

    String grade() {
        return marks >= 85 ? "A" : "B";
    }
}

public class Main {
    public static void main(String[] args) {
        Student s = new Student("Asha", 92);
        Student t = new Student("Ravi", 74);
        System.out.println(s.name + " " + s.grade() + ", " + t.name + " " + t.grade());
    }
}
```

```text
Asha A, Ravi B
```

- `new Student(...)` creates an object on the heap and runs the **constructor**.
- A constructor has the **same name as the class** and **no return type**.
- `this` means "this object" — it separates the field `this.name` from the parameter `name`.

## 2. Constructors: default, overloaded, chained

If you write **no** constructor, Java gives a default no-argument one. Once you write any constructor, that default disappears.

```java
class Product {
    String name;
    double price;

    Product() {
        this("Unknown", 0);            // calls the other constructor
    }
    Product(String name, double price) {
        this.name = name;
        this.price = price;
    }
    @Override
    public String toString() {
        return name + " ₹" + price;
    }
}

public class Main {
    public static void main(String[] args) {
        System.out.println(new Product());
        System.out.println(new Product("Pen", 10));
    }
}
```

```text
Unknown ₹0.0
Pen ₹10.0
```

`toString()` decides what `println(object)` shows. Without it you get something like `Product@1b6d3586`.

## 3. static: belongs to the class, not to objects

```java
class Counter {
    static int created = 0;   // one copy shared by all objects
    int id;                   // each object has its own

    Counter() {
        created++;
        id = created;
    }
    static void report() {    // static method: no "this", can't use id
        System.out.println("objects created: " + created);
    }
}

public class Main {
    public static void main(String[] args) {
        Counter a = new Counter(), b = new Counter(), c = new Counter();
        System.out.println(a.id + " " + c.id);
        Counter.report();
    }
}
```

```text
1 3
objects created: 3
```

`main` is static because the JVM calls it **before** any object exists.

## 4. Encapsulation: private fields + getters/setters

Hide the data (`private`) and allow access only through methods that can **check** the values.

```java
class BankAccount {
    private double balance;

    public double getBalance() { return balance; }

    public void deposit(double amount) {
        if (amount <= 0) throw new IllegalArgumentException("amount must be positive");
        balance += amount;
    }
    public boolean withdraw(double amount) {
        if (amount > balance) return false;
        balance -= amount;
        return true;
    }
}

public class Main {
    public static void main(String[] args) {
        BankAccount acc = new BankAccount();
        acc.deposit(1000);
        System.out.println(acc.withdraw(300) + " " + acc.withdraw(5000) + " " + acc.getBalance());
    }
}
```

```text
true false 700.0
```

Nobody can write `acc.balance = -500` from outside — the class protects its own rules.

## Access modifiers

| Modifier | Visible in |
|---|---|
| `private` | the same class only |
| (none) "default" | the same package |
| `protected` | same package + subclasses |
| `public` | everywhere |

## Common mistakes

- Writing `name = name;` in a constructor (assigns the parameter to itself). Use `this.name = name;`.
- Adding a return type to a constructor (it becomes a normal method).
- Using instance fields inside a static method.

## Quick recap

- Class = fields + constructors + methods; `new` creates objects.
- `this` refers to the current object; `this(...)` chains constructors.
- `static` members belong to the class and are shared.
- Encapsulation: private fields + public methods that check rules.
- Override `toString()` for readable output.


Practice quiz and free certificate: https://skills101.in/learn/java/java-classes-and-objects