Week 1

Environment setup

How Java works

Types and Variables

Arrays

Basic IO

Control Flow

Packages

OOP in Java

Static Members

Practice

Assignment

Back end Track

🎯 Learning Objectives

By the end of this module, you will be able to:


1. From JavaScript Classes to Java Classes

You already know the concept of classes from the Core Program. In JavaScript, a class looks like this:

class Person {
    constructor(name, age) {
        this.name = name;
        this.age  = age;
    }

    greet() {
        console.log(`Hi, I'm ${this.name}`);
    }
}

Java classes express the same idea but with stricter rules — every field has an explicit type, every method declares what it returns, and access to data is controlled deliberately.

public class Person {
    String name;
    int    age;

    public void greet() {
        System.out.println("Hi, I'm " + name);
    }
}

The rest of this module builds this class up step by step into a well-structured, production-quality Java class.


2. Defining a Class: Fields and Methods

A class is a blueprint. It describes what an object has (fields) and what it does (methods).

public class Person {

    // Fields — what a Person has
    String name;
    int    age;
    String email;

    // Method — what a Person does
    public void introduce() {
        System.out.println("Hi, I'm " + name + " and I'm " + age + " years old.");
    }
}
Concept JavaScript Java
Data on an object this.name = name String name; declared at class level
Method greet() { ... } public void greet() { ... } with return type
Type declaration Not required Required for every field and method

3. Creating Objects with new

A class definition is just a blueprint. To actually use it, you create an instance — a concrete object built from that blueprint — using the new keyword.

// JavaScript
const person = new Person("Alice", 30);

// Java
Person person = new Person();
person.name = "Alice";
person.age  = 30;

person.introduce(); // Hi, I'm Alice and I'm 30 years old.

Each object created from the same class has its own independent copy of the fields:

Person p1 = new Person();
Person p2 = new Person();

p1.name = "Alice";
p2.name = "Bob";

System.out.println(p1.name); // Alice
System.out.println(p2.name); // Bob — completely separate from p1

4. Constructors

Setting fields one by one after creation is verbose and error-prone. A constructor solves this — it runs automatically when new is called and sets up the object's initial state.

Default Constructor

A constructor with no parameters. Java provides one silently if you don't write any constructor yourself, but it's good practice to be explicit.

public class Person {
    String name;
    int    age;

    // Default constructor
    public Person() {
        name = "Unknown";
        age  = 0;
    }
}
Person p = new Person();
System.out.println(p.name); // Unknown

Parameterised Constructor

Accepts values at creation time — the most common pattern:

public class Person {
    String name;
    int    age;

    public Person(String name, int age) {
        this.name = name;
        this.age  = age;
    }
}
Person alice = new Person("Alice", 30);
System.out.println(alice.name); // Alice

💡 Once you define any constructor, Java no longer provides the silent default one. If you still want a no-argument constructor alongside a parameterised one, you must write both explicitly.


5. The this Keyword

this refers to the current object — the specific instance the method or constructor is running on.

You already know this from JavaScript, but Java uses it more consistently and for a clearer purpose.

Disambiguating fields from parameters

The most common use of this — when a constructor parameter has the same name as a field:

public Person(String name, int age) {
    this.name = name; // this.name = field, name = parameter
    this.age  = age;
}

Without this, the assignment name = name would just assign the parameter to itself — the field would never be set.

🔍 In JavaScript, this can change depending on how a function is called — a source of many bugs. In Java, inside an instance method or constructor, this always refers to the current object. No surprises.

Calling another constructor with this()

this() can be used inside a constructor to call another constructor in the same class — useful for sharing initialisation logic:

public Person() {
    this("Unknown", 0); // delegates to the parameterised constructor
}

public Person(String name, int age) {
    this.name = name;
    this.age  = age;
}

⚠️ this() must be the first statement in a constructor if used.


6. Constructor Overloading

Just like method overloading, you can have multiple constructors as long as their parameter lists differ. Java picks the right one based on what you pass to new.

public class Person {
    String name;
    int    age;
    String email;

    // 1. No info available yet
    public Person() {
        this("Unknown", 0, "");
    }

    // 2. Name and age only
    public Person(String name, int age) {
        this(name, age, "");
    }

    // 3. Full details
    public Person(String name, int age, String email) {
        this.name  = name;
        this.age   = age;
        this.email = email;
    }
}
Person p1 = new Person();                          // Unknown, 0, ""
Person p2 = new Person("Bob", 25);                 // Bob, 25, ""
Person p3 = new Person("Alice", 30, "[email protected]"); // Alice, 30, [email protected]

Each constructor chains upward to the most complete one using this() — keeping the actual initialisation logic in one place.


7. Calling Methods on Objects

Once you have an object, you call its methods using dot notation — identical to JavaScript:

Person alice = new Person("Alice", 30, "[email protected]");

alice.introduce();

Methods have access to all the object's fields directly, and can use this to be explicit:

public void introduce() {
    System.out.println("Hi, I'm " + this.name + " and I'm " + this.age + " years old.");
}

💡 Writing this.name vs just name inside a method is a matter of style when there's no naming conflict — both work. Many teams prefer this. for clarity; others omit it. Pick one convention and be consistent.


8. Access Modifiers

Access modifiers control which other classes can see and use a field or method. This is the mechanism that makes encapsulation possible.

Modifier Accessible from
public Anywhere
private This class only
protected This class, same package, and subclasses
(none) — package-private This class and same package only
public class Person {
    public  String name;     // anyone can read/write
    private int    age;      // only code inside Person can touch this
    protected String email;  // Person, same package, and subclasses
    String city;             // package-private — same package only
}

In practice, the two you'll use most day-to-day are public and private. protected becomes important when you work with inheritance in later weeks.


9. Encapsulation