IT234 Object Oriented Programming with Java

Object Oriented Programming with JavaUnit 311 min read

Classes, Objects, Constructors & Member Access in Java

Unit 3 of Object Oriented Programming with Java covers how to define classes, instantiate objects, use constructors (default/no-arg, parameterized), and control member access via modifiers (private, protected, public). It explains the lifecycle of objects, memory allocation, and how to model real-world entities in code

TAKEAWAYS:

  • A class is a blueprint for objects, while an object is an instance of that class with actual memory allocation.
  • Constructors initialize objects and can be overloaded to support different initialization patterns.
  • Access modifiers (private, protected, public) enforce encapsulation by controlling visibility of class members.
  • The this keyword distinguishes instance variables from parameters and enables constructor chaining.
  • Objects are stored in the heap memory, while class definitions reside in the method area.
  • Static members belong to the class itself, not individual objects, and are shared across all instances.

Core Concepts: Classes and Objects

What is a Class?

A class is a user-defined blueprint or prototype from which objects are created. It defines:

  • Attributes (data members/variables)
  • Methods (functions/procedures)
  • Constructors (special methods for object initialization)
class Student {
    // Attributes (data members)
    String name;
    int rollNo;
    String department;

    // Methods (functions)
    void display() {
        System.out.println("Name: " + name + ", Roll No: " + rollNo);
    }
}

Visualization: Class Structure

classDiagram
    class Student {
        -String name
        -int rollNo
        -String department
        +void display()
    }

What is an Object?

An object is an instance of a class. When a class is defined, no memory is allocated, but when an object is created, memory is allocated in the heap for that object.

public class Main {
    public static void main(String[] args) {
        // Creating an object of Student class
        Student student1 = new Student();
        student1.name = "Ramesh";
        student1.rollNo = 101;
        student1.display();
    }
}

Output:

Name: Ramesh, Roll No: 101

Memory Allocation Visualization

classDiagram
    class Main {
        +static void main(String[] args)
    }
    class Student {
        -String name
        -int rollNo
        -String department
        +void display()
    }
    Main "1" --> "1" Student : creates

Constructors in Java

Default Constructor

If no constructor is defined in a class, Java provides a default constructor (no-argument constructor) that initializes the object with default values (e.g., 0 for numbers, null for objects).

class Car {
    String model;
    int year;
}

// Default constructor is automatically provided by Java
Car myCar = new Car(); // model = null, year = 0

Parameterized Constructor

A parameterized constructor allows you to initialize objects with specific values.

class Car {
    String model;
    int year;

    // Parameterized constructor
    Car(String model, int year) {
        this.model = model;
        this.year = year;
    }
}

Car myCar = new Car("Toyota", 2020);

Constructor Overloading

Java allows constructor overloading, where multiple constructors with different parameters are defined.

class Car {
    String model;
    int year;

    // Constructor 1: No arguments
    Car() {
        this.model = "Unknown";
        this.year = 0;
    }

    // Constructor 2: Two arguments
    Car(String model, int year) {
        this.model = model;
        this.year = year;
    }
}

Constructor Overloading Visualization

flowchart TD
    A["Car myCar1 = new Car()"] --> B["Default Constructor<br/>model='Unknown', year=0"]
    C["Car myCar2 = new Car('Toyota', 2020)"] --> D["Parameterized Constructor<br/>model='Toyota', year=2020"]

The this Keyword

The this keyword refers to the current object and is used to:

  1. Distinguish between instance variables and parameters.
  2. Invoke one constructor from another (constructor chaining).
class Student {
    String name;
    int rollNo;

    // Constructor with parameters
    Student(String name, int rollNo) {
        this.name = name; // 'this.name' refers to instance variable
        this.rollNo = rollNo;
    }

    // Constructor chaining
    Student() {
        this("Unknown", 0); // Calls the parameterized constructor
    }
}

Constructor Chaining Visualization

flowchart TD
    A["Student s1 = new Student()"] --> B["Student()<br/>this('Unknown', 0)"]
    B --> C["Student('Unknown', 0)<br/>name='Unknown', rollNo=0"]

Access Modifiers in Java

Access modifiers control the visibility of class members (variables and methods). There are four types:

Modifier Within Class Within Package Subclass (Inherited) Outside Package
public ✅ Yes ✅ Yes ✅ Yes ✅ Yes
protected ✅ Yes ✅ Yes ✅ Yes ❌ No
default ✅ Yes ✅ Yes ❌ No ❌ No
private ✅ Yes ❌ No ❌ No ❌ No

Example:

class BankAccount {
    private String accountNumber; // Only accessible within BankAccount
    protected double balance;     // Accessible within package and subclasses
    public String ownerName;      // Accessible everywhere
}

Static Members in Java

Static members belong to the class rather than individual objects. They are shared across all instances of the class.

class Counter {
    static int count = 0; // Static variable

    Counter() {
        count++; // Incremented every time an object is created
    }
}

Counter c1 = new Counter();
Counter c2 = new Counter();
System.out.println(Counter.count); // Output: 2

Static Method Example:

class MathUtils {
    static int add(int a, int b) {
        return a + b;
    }
}

int sum = MathUtils.add(5, 7); // No object needed

In the Real World

  1. eSewa (Nepal):

    • Class: User
    • Objects: Millions of eSewa users (e.g., user1, user2).
    • Constructor: Initializes user details like name, phoneNumber, and balance.
    • Static Method: calculateTransactionFee() computes fees for all users uniformly.
  2. Khalti (Nepal):

    • Class: Transaction
    • Objects: Each payment request (e.g., transaction123, transaction456).
    • Constructor: Takes amount, sender, receiver, and timestamp as parameters.
    • Access Modifiers: private fields like transactionId ensure security.
  3. Bank Loan Processing (Nepal):

    • Class: Loan
    • Objects: Individual loans (e.g., loan1001, loan1002).
    • Constructor Overloading:
      • Loan(double principal, int tenure) for standard loans.
      • Loan(double principal, int tenure, double interestRate) for custom interest rates.
    • Static Method: calculateEMI() computes monthly installments for all loans.

Worked Example: Modeling a Daraz Order Queue

Scenario: Daraz uses a queue to manage orders. Each order is an object of the Order class, and the queue processes orders in FIFO (First-In-First-Out) order.

class Order {
    int orderId;
    String customerName;
    double amount;

    Order(int orderId, String customerName, double amount) {
        this.orderId = orderId;
        this.customerName = customerName;
        this.amount = amount;
    }
}

public class OrderQueue {
    static Queue<Order> orderQueue = new LinkedList<>();

    public static void addOrder(Order order) {
        orderQueue.add(order);
    }

    public static Order processNextOrder() {
        return orderQueue.poll(); // Removes and returns the first order
    }
}

Visualization: Order Queue Processing

flowchart TD
    A["OrderQueue.addOrder(new Order(1, 'Ramesh', 5000))"] --> B["Queue: [Order1]"]
    C["OrderQueue.addOrder(new Order(2, 'Sita', 3000))"] --> D["Queue: [Order1, Order2]"]
    E["OrderQueue.processNextOrder()"] --> F["Queue: [Order2]<br/>Returns Order1"]
    G["OrderQueue.processNextOrder()"] --> H["Queue: []<br/>Returns Order2"]

Trace Table:

Step Action Queue State Returned Order
1 addOrder(Order1) [Order1] -
2 addOrder(Order2) [Order1, Order2] -
3 processNextOrder() [Order2] Order1
4 processNextOrder() [] Order2

Common Pitfalls and Best Practices

  1. Default Constructor:

    • If you define any constructor, Java does not provide a default constructor. Always include a no-arg constructor if needed.
    • ❌ Wrong:
      class Example {
          Example(int x) {} // No default constructor
      }
      Example e = new Example(); // Error!
      
    • ✅ Correct:
      class Example {
          Example() {} // Default constructor
          Example(int x) {}
      }
      
  2. Constructor Chaining:

    • Use this() to call another constructor in the same class.
    • Use super() to call a parent class constructor (covered in Unit 4).
  3. Access Modifiers:

    • Use private for sensitive data (e.g., passwords, API keys).
    • Use public for methods that should be accessible to all classes.
  4. Static vs. Instance Members:

    • Use static for methods/variables that are shared (e.g., Math.PI, Counter.count).
    • Use instance members for object-specific data (e.g., student.name).

Exam Tip

  1. Class vs. Object:

    • Always distinguish between a class (blueprint) and an object (instance). Examiners often ask for code snippets showing both.
  2. Constructor Overloading:

    • Be ready to write multiple constructors for a single class. Show how they initialize objects differently.
  3. this Keyword:

    • Use this in constructors to avoid ambiguity between instance variables and parameters. Example:
      class Person {
          String name;
          Person(String name) {
              this.name = name; // Correct
              // name = name; // Error: Ambiguous
          }
      }
      
  4. Access Modifiers:

    • Memorize the visibility rules for private, protected, public, and default. Questions often test this with hypothetical scenarios.
  5. Static Members:

    • Know when to use static. Static methods cannot access instance variables directly (they belong to the class, not objects).
  6. Real-World Applications:

    • Relate concepts to Nepali apps (e.g., eSewa users as objects, Khalti transactions as constructor parameters). Examiners love practical connections!
  7. Code Tracing:

    • Practice tracing constructor calls and object initialization. Example:
      class Test {
          Test() { System.out.print("A"); }
          Test(int x) { this(); System.out.print("B"); }
      }
      public class Main {
          public static void main(String[] args) {
              new Test(5); // Output: AB
          }
      }
      
      Explanation:
      • Test(5) calls this() → Test() prints A.
      • Then Test(5) prints B.
      • Output: AB.

Final Note: Mastering classes, objects, and constructors is the foundation of OOP in Java. Focus on:

  1. Writing correct constructors (default, parameterized, overloaded).
  2. Using this and constructor chaining.
  3. Applying access modifiers properly.
  4. Differentiating static vs. instance members.

Practice by modeling real-world entities (e.g., bank accounts, Daraz orders, eSewa users) as classes and objects. This will not only help in exams but also in building real applications!

Based on the TU BIM syllabus for Object Oriented Programming with Java (IT234), unit 3.

Discussion

Loading…