# Java OOPs

Here is a Java OOPs Revision Guide: Part 1 focused on the absolute fundamentals: Syntax, Classes, and Objects.

Since you are new to Java, think of this as your "Cheat Sheet" to understand how a Java file is structured and how to bring your code to life.

***

## Topic Mindmap

```
[Java OOPs — Syntax Reference]
├── Part 1: Class and Object
│   ├── Class: blueprint (recipe); Object: instance (cake)
│   ├── new keyword: allocates heap memory + calls constructor
│   ├── this keyword: refers to current object instance
│   └── static members: shared across all instances (no this)
├── Part 2: Arrays and Strings
│   ├── Arrays: fixed-size, zero-indexed, int[] arr = new int[5]
│   ├── String: immutable; == compares reference, .equals() compares value
│   └── StringBuilder: mutable, use for concatenation in loops
├── Part 3: Methods and Control Flow
│   ├── Method signature: return type + name + parameters
│   ├── void: no return value
│   ├── Overloading: same name, different parameter types/count
│   └── Control flow: if/else, for, while, switch
├── Part 4: Constructors Deep Dive
│   ├── Default constructor: provided by compiler if none defined
│   ├── Parameterized constructor: initializes fields on creation
│   ├── Constructor chaining: this() calls another constructor
│   └── Cannot be called after object creation — use a factory method
├── Access Modifiers
│   ├── private: class only
│   ├── protected: class + subclasses + same package
│   ├── public: everywhere
│   └── default (package-private): same package only
├── Static vs Instance
│   ├── static field: one copy per class (counter, constants)
│   ├── instance field: one copy per object (name, balance)
│   ├── static method: no access to this or instance fields
│   └── Use static for utility methods (Math.abs, Collections.sort)
├── Key Java Mechanics
│   ├── Primitive types: int, double, boolean, char (stack allocated)
│   ├── Reference types: objects, arrays (heap allocated, null default)
│   └── Pass-by-value: primitives copy value; objects copy reference
└── Interview Angles
    ├── What is the difference between == and .equals()?
    ├── Why are Strings immutable in Java?
    ├── When does a default constructor disappear?
    └── What is the output of static initializer blocks?
```

## Part 1

***

### 1. The Core Concept: Class vs. Object

Before writing code, you must understand the mental model.

* Class (The Blueprint): A logical template. It defines *what* data and actions an entity will have, but it doesn't occupy memory for data yet.
* Object (The House): A physical instance of the class. It occupies memory and holds actual data. You can build thousands of objects from one class.

Analogy:

* Class: The recipe for a Chocolate Cake.
* Object: The actual cake sitting on your table.

***

### 2. The Anatomy of a Java Class

Every Java class follows a specific structure. Here is the skeleton syntax you need to memorize.

Java

```java
// 1. Package Declaration (Optional but recommended)
package com.myapp.basics; 

// 2. Imports (Bringing in other tools)
import java.util.Scanner; 

// 3. Class Declaration (PascalCase)
public class Student { 

    // 4. Fields / Attributes (State) -> camelCase
    String name;  
    int age;      

    // 5. Methods (Behavior) -> camelCase
    public void study() {
        System.out.println(name + " is studying.");
    }
}
```

***

### 3. Constructors: The "Setup" Method

When you create an object, you often want to set it up immediately (e.g., giving a Student a name). This is done using a Constructor.

* Rule 1: Must have the exact same name as the class.
* Rule 2: Must not have a return type (not even `void`).
* Rule 3: It runs automatically when you use the `new` keyword.

Java

```java
public class Student {
    String name;

    // Default Constructor (No arguments)
    public Student() {
        name = "Unknown";
    }

    // Parameterized Constructor (With arguments)
    public Student(String inputName) {
        name = inputName;
    }
}
```

***

### 4. The `this` Keyword

This is a reference variable that points to the current object. It is mostly used to resolve naming conflicts when your parameter name is the same as your field name.

Java

```java
public class Car {
    String model; // Field (belongs to object)

    // Constructor
    public Car(String model) { // Parameter (local variable)
        // model = model; // AMBIGUITY! Computer is confused.
        
        this.model = model; 
        // "this.model" refers to the Class Field.
        // "model" refers to the Parameter passed in.
    }
}
```

***

### 5. Creating Objects (The `new` Keyword)

To use a class, you must instantiate it in a `main` method.

Syntax:

`ClassName objectName = new Constructor();`

* `ClassName`: The type of variable.
* `objectName`: The reference variable name (like a remote control).
* `=`: Assignment operator.
* `new`: The magic keyword that allocates memory in the heap.
* `Constructor()`: Initializes the object.

***

### 6. Static vs. Non-Static (Instance)

This is often the most confusing part for beginners.

* Instance (Non-Static): Belongs to the Object. Every object has its own copy.
  * *Example:* `eyeColor`. Your eye color is unique to you.
* Static: Belongs to the Class. All objects share one single copy.
  * *Example:* `populationCount`. If a baby is born, the count goes up for *everyone*.

Java

```java
public class Human {
    String name;            // Instance variable (Unique per person)
    static int population;  // Static variable (Shared by all Humans)

    public Human(String name) {
        this.name = name;
        population++; // Increasing the shared counter
    }
}
```

***

### 7. Putting It All Together: A "SmartPhone" Example

Here is a complete, runnable code block combining everything above.

Java

```java
// 1. The Class Definition
class SmartPhone {
    // Fields (State)
    String brand;
    int batteryLevel;
    static String osType = "Android"; // Shared by all phones of this class

    // Constructor
    public SmartPhone(String brand, int batteryLevel) {
        this.brand = brand;
        this.batteryLevel = batteryLevel;
    }

    // Method (Behavior)
    public void call(String number) {
        System.out.println(this.brand + " is calling " + number);
    }
    
    // Method to show static vs instance data
    public void showStats() {
        System.out.println("Phone: " + brand + " | OS: " + osType);
    }
}

// 2. The Main Execution Class
public class Main {
    public static void main(String[] args) {
        // Creating Object 1
        SmartPhone p1 = new SmartPhone("Samsung", 85);
        
        // Creating Object 2
        SmartPhone p2 = new SmartPhone("Pixel", 90);

        // Calling methods
        p1.call("555-0199");
        p2.showStats(); // Output: Phone: Pixel | OS: Android

        // Changing a static variable affects EVERYONE
        SmartPhone.osType = "Android 14";
        
        System.out.println("After Update:");
        p1.showStats(); // Output: Phone: Samsung | OS: Android 14
        p2.showStats(); // Output: Phone: Pixel   | OS: Android 14
    }
}
```

#### Quick Syntax Cheat Sheet

| **Action**    | **Syntax**                                |
| ------------- | ----------------------------------------- |
| Define Class  | `class Name { ... }`                      |
| Create Object | `Name obj = new Name();`                  |
| Constructor   | `public Name() { ... }` (No return type!) |
| Access Method | `obj.methodName();`                       |
| Access Field  | `obj.fieldName;`                          |
| Refer to self | `this.variableName`                       |
| Shared Data   | `static int variableName`                 |

## Part 2

These are often where beginners face their first "gotchas" (like index errors or string comparison issues), so I will highlight those specifically.

***

### 1. Java Arrays

"The Fixed Container"

An Array is a container object that holds a fixed number of values of a single type. Once you create an array with a specific size (e.g., 5 slots), you cannot change its size.

* Key Characteristic: Fixed Size.
* Indexing: Starts at 0 (not 1). The last index is `length - 1`.
* Performance: Very fast access if you know the index.

**A. Syntax & Creation**

There are two main ways to create an array.

Method 1: Declaration + Memory Allocation (Empty)

Use this when you know *how many* items you need, but not *what* they are yet.

Java

```java
// Syntax: type[] name = new type[size];
int[] scores = new int[5]; // Creates 5 slots: [0, 0, 0, 0, 0]

// Setting values
scores[0] = 95;
scores[1] = 88;
```

Method 2: Initialization (Filled)

Use this when you already know the values.

Java

```java
// Syntax: type[] name = {values};
String[] names = {"Alice", "Bob", "Charlie"};
```

**B. Iterating (Looping)**

You will almost always use a loop to go through an array.

Java

```java
int[] numbers = {10, 20, 30, 40, 50};

// 1. Classic For Loop (Good if you need the Index)
for (int i = 0; i < numbers.length; i++) {
    System.out.println("Index " + i + ": " + numbers[i]);
}

// 2. Enhanced For-Each Loop (Good for just reading values)
// Read as: "For each 'num' in 'numbers'..."
for (int num : numbers) {
    System.out.println("Value: " + num);
}
```

**C. The "Gotcha": ArrayIndexOutOfBoundsException**

This is the most common error. It happens if you try to access a slot that doesn't exist.

Java

```java
int[] arr = new int[3]; // Indices are 0, 1, 2
// System.out.println(arr[3]); // ERROR! Index 3 is the 4th slot.
```

***

### 2. Java Strings

"The Immutable Text"

In Java, a `String` is an Object, not a primitive type (like `int` or `char`). This means it has methods you can call.

* Key Characteristic: Immutability. Once a String object is created, it cannot be changed. If you "modify" a string, Java actually creates a generic *new* string in memory and discards the old one.

**A. Creation: Literal vs. New**

How you create a string matters for memory.

1. String Literal (Recommended): Uses the "String Constant Pool" to save memory. If you write "Hello" twice, Java reuses the same object.

   Java

   ```java
   String s1 = "Hello";
   ```
2. New Keyword: Forces a new object in Heap memory every time.

   Java

   ```java
   String s2 = new String("Hello");
   ```

**B. The Comparison Trap (`==` vs `.equals()`)**

This is the #1 interview question for beginners.

* `==`: Compares references (memory addresses). "Are these the exact same object?"
* `.equals()`: Compares content (values). "Do these hold the same text?"

Java

```java
String s1 = "Java";
String s2 = "Java";           // Reuses s1 from Pool
String s3 = new String("Java"); // Forces new object

System.out.println(s1 == s2);       // true (Same memory address)
System.out.println(s1 == s3);       // false (Different memory addresses)
System.out.println(s1.equals(s3));  // true (Content is identical) -> USE THIS!
```

**C. Essential String Methods**

You don't need to memorize all of them, but these 5 are essential:

1. `length()`: Returns the count of characters.
2. `charAt(index)`: Returns the character at a specific position.
3. `substring(start, end)`: Extracts a portion of the text.
4. `toLowerCase()` / `toUpperCase()`: Changes case.
5. `trim()`: Removes whitespace from start and end.

***

### 3. Practical Revision: A "Student Database" Code

Here is a single program combining Arrays and Strings to simulate a mini-database.

Java

```java
public class StudentDatabase {
    public static void main(String[] args) {
        // 1. Array of Strings
        String[] students = {"Alice", "Bob", "Charlie", "David"};
        
        // 2. Array of Integers (Parallel array for grades)
        int[] grades = {85, 42, 90, 76};

        System.out.println("--- Class Report ---");

        // 3. Loop through the array
        for (int i = 0; i < students.length; i++) {
            String name = students[i];
            int score = grades[i];

            // String Manipulation: Convert to uppercase for display
            String displayName = name.toUpperCase();

            // Conditional Logic
            String result;
            if (score >= 50) {
                result = "PASSED";
            } else {
                result = "FAILED";
            }

            System.out.println(displayName + " : " + score + " -> " + result);
        }

        // 4. Demonstrate Immutability
        String original = "   Java   ";
        String cleaned = original.trim(); // original is NOT changed
        
        System.out.println("\nOriginal: '" + original + "'");
        System.out.println("Cleaned:  '" + cleaned + "'");
    }
}
```

#### Quick Syntax Cheat Sheet

| **Action**      | **Syntax/Method**         | **Note**                                 |
| --------------- | ------------------------- | ---------------------------------------- |
| Create Array    | `int[] arr = new int[5];` | Size is fixed at 5.                      |
| Get Array Size  | `arr.length`              | It's a property (no parenthesis).        |
| Get String Size | `str.length()`            | It's a method (needs parenthesis).       |
| Compare Strings | `str1.equals(str2)`       | NEVER use `==` for text content.         |
| Get Char        | `str.charAt(0)`           | Gets the first letter.                   |
| Get Substring   | `str.substring(0, 3)`     | Gets index 0, 1, and 2 (3 is exclusive). |

## Part 3

Here is Java OOPs Revision Guide: Part 3, covering Methods (the behavior) and Control Flow (the logic).

This is where your static code starts to actually *do* things.

***

### 1. Java Methods

"The Verbs"

A method is a block of code that runs only when it is called. You use methods to break a complex problem into small, manageable chunks (like "login", "calculateTotal", "printReceipt").

**A. The Anatomy of a Method**

You need to memorize this signature structure:

`AccessModifier ReturnType MethodName(Parameters) { Body }`

* Access Modifier: `public` (everyone can see), `private` (only this class), etc.
* Return Type: The data type the method gives back (e.g., `int`, `String`). Use `void` if it gives back nothing.
* Method Name: camelCase (e.g., `calculateTax`).
* Parameters: Inputs inside the parentheses `(type name)`.

**B. Return Types vs. Void**

This is a common point of confusion.

* `void`: Performs an action but returns no value. (e.g., Printing to console, saving to DB).
* Data Type (`int`, `String`, etc.): Calculates and returns a value to the caller.

Java

```java
public class Calculator {
    
    // 1. VOID Method (Action only)
    public void printWelcome() {
        System.out.println("--- Welcome to Calculator ---");
        // No 'return' statement needed
    }

    // 2. INT Method (Must return an int)
    public int add(int a, int b) {
        int sum = a + b;
        return sum; // MUST match the 'int' declared above
    }
}
```

**C. Method Overloading**

This is a core OOP concept (Compile-time Polymorphism). You can have multiple methods with the same name as long as their parameters are different.

Java

```
public class Printer {
    // Prints a String
    public void print(String text) {
        System.out.println(text);
    }

    // Prints an Integer (Same name, different input type)
    public void print(int number) {
        System.out.println("Number: " + number);
    }
    
    // Prints two Strings (Same name, different number of inputs)
    public void print(String text1, String text2) {
        System.out.println(text1 + " & " + text2);
    }
}
```

***

### 2. Control Flow statements

"The Logic / The Brain"

Control flow dictates the order in which statements are executed. Without this, your code just reads from top to bottom like a book.

**A. Conditional Logic (If / Else / Switch)**

Use If/Else for ranges or complex conditions. Use Switch for specific fixed values.

Java

```
int battery = 15;

// IF-ELSE LADDER
if (battery > 50) {
    System.out.println("Green Light");
} else if (battery > 20) {
    System.out.println("Yellow Light");
} else {
    System.out.println("Red Light");
}

// SWITCH STATEMENT (Clean for specific cases)
int day = 3;
switch (day) {
    case 1:
        System.out.println("Monday");
        break; // Don't forget break, or it falls through!
    case 2:
        System.out.println("Tuesday");
        break;
    default:
        System.out.println("Midweek");
}
```

**B. Loops (For, While, Do-While)**

Loops allow you to repeat code.

* `for` loop: Use when you know exactly how many times to loop (e.g., "Run 10 times").
* `while` loop: Use when you don't know the number of iterations (e.g., "Run until user types 'exit'").
* `do-while` loop: Guaranteed to run at least once (e.g., "Show menu, then ask to continue").

Java

```
// 1. FOR Loop (Fixed)
for (int i = 1; i <= 5; i++) {
    System.out.print(i + " "); // Output: 1 2 3 4 5
}

// 2. WHILE Loop (Condition based)
int count = 5;
while (count > 0) {
    System.out.print(count + " "); // Output: 5 4 3 2 1
    count--;
}
```

***

### 3. Combined Practice: A "Mini ATM" Class

Here is how Methods and Control Flow work together in a real object.

Java

```java
public class ATM {
    // State (Data)
    private double balance;
    private int pin = 1234;

    // Constructor
    public ATM(double initialBalance) {
        this.balance = initialBalance;
    }

    // Method 1: Boolean Return Type (Logic)
    public boolean verifyPin(int inputPin) {
        if (inputPin == this.pin) {
            return true;
        } else {
            return false;
        }
    }

    // Method 2: Void Method with Control Flow
    public void withdraw(int amount) {
        // Validation Logic
        if (amount <= 0) {
            System.out.println("Error: Amount must be positive.");
        } else if (amount > balance) {
            System.out.println("Error: Insufficient Funds.");
        } else {
            // Success Logic
            balance = balance - amount;
            System.out.println("Success! Please take your $" + amount);
        }
    }
    
    // Method 3: Getter
    public double getBalance() {
        return balance;
    }
}

// Main Execution
public class Main {
    public static void main(String[] args) {
        ATM myAtm = new ATM(1000.0);
        
        // Using Logic (If/Else) with Method Calls
        if (myAtm.verifyPin(1234)) {
            System.out.println("PIN Accepted.");
            myAtm.withdraw(500); // Valid
            myAtm.withdraw(5000); // Invalid (Insufficient funds)
        } else {
            System.out.println("Wrong PIN!");
        }
    }
}
```

#### Quick Syntax Cheat Sheet

| **Keyword**   | **Purpose**                    | **Example**                 |
| ------------- | ------------------------------ | --------------------------- |
| `void`        | Method returns nothing         | `public void run() { ... }` |
| `return`      | Exits method & sends data back | `return a + b;`             |
| `break`       | Exits a loop or switch case    | `break;`                    |
| `continue`    | Skips current loop iteration   | `continue;`                 |
| `if (x == y)` | Checks equality                | `if (age == 18) { ... }`    |
| `!=`          | Checks "Not Equal"             | `if (age != 0) { ... }`     |
| `&&` / `\|\|` | Logical AND / OR               | `if (age > 18 && hasID)`    |

***

## Part 4

***

### 1. Constructors

"The Birth of an Object"

A constructor is a special method that is called automatically when you create an object (using `new`). Its main job is to initialize the object's fields.

* Rule: It must have the exact same name as the class and no return type.

**A. Default vs. Parameterized**

* Default Constructor: Has no arguments. Java provides an invisible one if you don't write *any* constructor.
* Parameterized Constructor: Takes arguments to set specific values during creation.

Java

```java
public class User {
    String name;

    // 1. No-Args Constructor (Default values)
    public User() {
        this.name = "Guest";
    }

    // 2. Parameterized Constructor (Custom values)
    public User(String name) {
        this.name = name;
    }
}
```

**B. Constructor Overloading**

Just like methods, you can have multiple constructors as long as their parameters are different. This gives users flexibility in how they create objects.

Java

```java
User u1 = new User();        // name = "Guest"
User u2 = new User("Alice"); // name = "Alice"
```

***

### 2. Static vs. Instance

"Shared vs. Unique"

This is the most critical memory concept in Java.

* Instance (Non-Static): Belongs to the Object. Each object has its own copy.
  * *Analogy:* Your Toothbrush. Everyone has their own.
* Static: Belongs to the Class. There is only one copy shared by all objects.
  * *Analogy:* The Bathroom Light. Everyone shares the same one.

**A. The `static` Keyword**

Use `static` for properties that should be common to all objects (like a counter or a constant).

Java

```java
public class Employee {
    String name;          // Instance: Unique to each employee
    static String company = "Google"; // Static: Shared by ALL employees

    public Employee(String name) {
        this.name = name;
    }
}

// Usage
Employee e1 = new Employee("John");
Employee e2 = new Employee("Jane");

// e1.company is "Google"
// e2.company is "Google"

// If we change it strictly using the Class Name:
Employee.company = "Alphabet"; 

// Now e1.company AND e2.company are both "Alphabet"!
```

**B. Static Methods**

Static methods can be called without creating an object. They are utility functions (like `Math.sqrt()`).

* *Restriction:* A static method cannot access instance variables (because it doesn't know *which* object you are talking about).

***

### 3. Access Modifiers

"The Security Guards"

Access modifiers determine which other classes can see and use your variables and methods.

| **Modifier** | **Keyword**    | **Visibility**               | **Analogy**                          |
| ------------ | -------------- | ---------------------------- | ------------------------------------ |
| Public       | `public`       | Everywhere (Global)          | Public Park (Anyone can enter)       |
| Private      | `private`      | Only inside the Same Class   | Your Diary (Only you can read)       |
| Protected    | `protected`    | Same Package + Subclasses    | Family Money (Family + Kids inherit) |
| Default      | *(no keyword)* | Only inside the Same Package | Office Water Cooler (Only coworkers) |

**Best Practice: Encapsulation**

Always make your fields `private` and your methods `public` (unless they are internal helper methods).

Java

```java
public class BankAccount {
    // 1. PRIVATE: No one can touch the money directly
    private double balance; 

    // 2. PUBLIC: Everyone can use the bank services
    public void deposit(double amount) {
        if (amount > 0) {
            this.balance += amount; // Safe internal access
        }
    }
}
```

***

### 4. Combined Revision Code

Here is a `School` system combining Constructors, Static logic, and Modifiers.

Java

```java
public class Student {
    // 1. Private Fields (Encapsulation)
    private String name;
    private int id;
    
    // 2. Static Field (Shared Counter)
    private static int totalStudents = 0;
    
    // 3. Constant (Final + Static)
    public static final String SCHOOL_NAME = "Lincoln High";

    // 4. Constructor
    public Student(String name) {
        this.name = name;
        // Auto-increment the shared ID counter
        totalStudents++; 
        this.id = totalStudents;
    }

    // 5. Static Method (Accessing static data only)
    public static int getTotalStudents() {
        return totalStudents;
    }

    // 6. Instance Method (Accessing instance data)
    public void introduce() {
        System.out.println("Hi, I am " + name + " (ID: " + id + ")");
        System.out.println("I go to " + SCHOOL_NAME);
    }
}

public class Main {
    public static void main(String[] args) {
        System.out.println("School: " + Student.SCHOOL_NAME);
        
        Student s1 = new Student("Alice");
        Student s2 = new Student("Bob");
        
        s1.introduce(); // ID: 1
        s2.introduce(); // ID: 2
        
        // Accessing static method directly from Class
        System.out.println("Total Enrolled: " + Student.getTotalStudents()); // Output: 2
    }
}
```

#### Quick Syntax Cheat Sheet

| **Feature**     | **Syntax**               | **When to use?**                           |
| --------------- | ------------------------ | ------------------------------------------ |
| Constructor     | `public ClassName() { }` | To setup default values.                   |
| Static Variable | `static int count;`      | For shared data (counters, constants).     |
| Static Method   | `static void run()`      | For utility tools (Math, Converters).      |
| Private         | `private int age;`       | ALWAYS for class fields (attributes).      |
| Public          | `public void getAge()`   | For methods meant for the outside world.   |
| Access Static   | `ClassName.variable`     | Don't use object names (e.g., `s1.count`). |


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://nishchalnishant.gitbook.io/system-design/06-lld/introduction/java-oops.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
