Object Oriented Programming in Java: Classes, Objects, and Memory Management
Object-Oriented Programming (OOP) is a fundamental programming paradigm that structures software design around data, or "objects," rather than functions and logic. By modeling real-world entities inside code, Java allows developers to organize complex systems into modular, reusable, and maintainable components.
1. The Naive Approach: Storing Data with Independent Variables
Before introducing Object-Oriented Programming, consider how state (data) is stored using procedural techniques. Suppose an application needs to store details about a student named Aditya.
// Storing details of Student 1 (Aditya) using independent variables
String name = "Aditya";
int age = 28;
int rollNumber = 1001;
String college = "IIT Guwahati";
If the system needs to manage a second student named Rohit, new independent variables must be created:
// Storing details of Student 2 (Rohit) using new variable names
String name2 = "Rohit";
int age2 = 28;
int rollNumber2 = 102;
String college2 = "IIT Guwahati";
Critical Architectural Problems
- High Variable Proliferation: Representing entities with properties requires independent variables scattered throughout the codebase.
- Lack of Conceptual Grouping: The compiler treats
name,age,rollNumber, andcollegeas isolated primitives. There is no structural boundary informing the program that these four variables belong to a single cohesive entity. - Complex Function Signatures: Passing a student to a function requires passing every property individually:
JAVA
void printStudentDetails(String name, int age, int rollNumber, String college) { // Risk of missing arguments or misordering types } - No Centralized Data Ownership/Authority: Because variables exist independently in memory, any part of the program can mutate an individual field without enforcing entity-level constraints.
2. Core Mental Model: What is Object-Oriented Programming?
Software is written to solve real-world problems. The physical world consists of distinct entities (people, places, physical items, bank accounts).
Object-Oriented Programming is a programming paradigm—a fundamental framework for thinking about and structuring code—that requires developers to mimic the real world within software.
Instead of managing floating variables, OOP encapsulates related data and behaviors into a single unified unit called an Object.
3. Selective Domain Modeling (Abstraction)
A single real-world human can play multiple roles depending on the context:
Key Rule of Domain Modeling: Software does not attempt to replicate every single physical attribute of a real-world object. It replicates only the attributes relevant to the specific problem domain.
- If building a College Management Portal, model the human as a Student with
rollNumber,college, andgrades. - If building an HR Portal, model the human as an Employee with
employeeId,department, andsalary.
4. Classes as Blueprints (User-Defined Data Types)
To create objects in Java, first define a Class. A class is an abstract blueprint or template. It occupies no physical memory for data storage; it simply defines what properties and behaviors instances of that class will possess.
Data Type Classification in Java
Defining a Custom Class in Java
class Student {
// State / Characteristics (Field Variables)
String name;
int age;
int rollNumber;
String college;
}
5. Instantiating Objects with the new Keyword
Creating an object from a class blueprint requires a two-step declaration and allocation process:
// Step 1: Declare a Reference Variable of type Student
Student s1;
// Step 2: Dynamically Instantiate the Object in Heap Memory
s1 = new Student();
// Combined Single-Line Syntax (Standard Industry Practice)
Student s2 = new Student();
Static vs. Dynamic Memory Allocation
- Compile-Time Allocation: Managed statically before program execution begins.
- Dynamic Memory Allocation (
newKeyword): Evaluated strictly at runtime. When Java encountersnew Student(), it dynamically requests a contiguous block of memory inside the Heap to hold all member variables defined inside theStudentclass.
6. Memory Model Breakdown: Stack vs. Heap
Understanding memory placement is critical for mastering Java object references.
Step-by-Step Memory Execution Mechanics
Student s1;: Allocates a reference variable nameds1inside the current execution frame on the Stack.new Student();: Allocates a memory block inside the Heap starting at an address (e.g.,1001). Heap objects themselves are unnamed.=Assignment: Assigns the heap memory address (1001) to the reference variables1in the Stack.
Crucial Distinction:
s1is not the object itself.s1is a Reference Variable that stores the memory address of an unnamed object residing in Heap memory.
7. Accessing State and Behavior via the Dot (.) Operator
Because reference variables hold memory addresses, direct operations on fields require dereferencing. Java provides the Dot (.) Operator to navigate from a reference variable in the Stack to its target instance in the Heap.
Syntax Workflow
s1 . name = "Aditya";
[Ref Var] [Navigate to Heap] [Target Field] [Assign] [Value Payload]
// Assigning state values to Heap memory locations via '.' operator
s1.name = "Aditya";
s1.age = 28;
s1.rollNumber = 1001;
s1.college = "IIT Guwahati";
// Retrieving values via '.' operator
System.out.println(s1.name); // Dereferences s1 address and reads 'name' field
8. Unifying State (Data) and Behavior (Methods)
Objects do not just contain static attributes (state); they perform actions (behavior).
Real-World Entity Example: Animal
- Characteristics:
type(Carnivore/Herbivore),numberOfLegs. - Behaviors:
makeSound(),eat(),run().
In procedural programming, data variables and functions operating on data are kept separate. In OOP, methods are encapsulated inside the class along with variables, giving them direct internal access to object state.
Encapsulating Behavior inside a Java Class
class Student {
// State Attributes
String name;
int age;
int rollNumber;
String college;
// Behavior 1: Internal logic to mark attendance
void markAttendance() {
// Direct access to internal field 'name' without passing parameters
System.out.println("Attendance marked by " + name);
}
// Behavior 2: Internal logic to display student payload
void printDetails() {
System.out.println(name + ", " + age + ", " + rollNumber + ", " + college);
}
}
Invoking Methods via Objects
s1.markAttendance(); // Output: Attendance marked by Aditya
s2.markAttendance(); // Output: Attendance marked by Rohit
s1.printDetails(); // Output: Aditya, 28, 1001, IIT Guwahati
Notice that printDetails() requires zero function parameters because it operates directly on the instance fields of the calling object.
9. Java Naming Conventions
Java relies on clear naming conventions to keep code readable and maintainable.
Note: These are standard conventions, not compiler enforced rules. Following them makes code standard and easy to debug across the Java ecosystem.
10. Non-Physical Abstractions & Digital Objects
OOP principles extend beyond modeling physical real-world items (like humans or animals). Complex, non-physical concepts should also be modeled as classes whenever they bundle multiple properties together.
Common Digital & Non-Physical Classes
// Non-physical entity: Bank Account
class BankAccount {
String accountNumber;
String ifscCode;
double balance;
String branchName;
void deposit(double amount) {
balance += amount;
}
}
// Non-physical entity: Geographical Coordinates
class Location {
double latitude;
double longitude;
}
Physical vs. Digital Objects
Digital objects can also include utility methods (like printDetails()) that wouldn't exist on physical objects in the real world. This reflects their specialized digital behavior within software systems.
11. Complete Flow Walkthrough & Code Evolution
Naive Implementation (Procedural / Unstructured)
public class NaiveDemo {
public static void main(String[] args) {
String name1 = "Aditya";
int age1 = 28;
int roll1 = 1001;
String name2 = "Rohit";
int age2 = 28;
int roll2 = 102;
// Disjointed helper function call requiring all individual variables
printDetails(name1, age1, roll1);
printDetails(name2, age2, roll2);
}
static void printDetails(String name, int age, int roll) {
System.out.println(name + " | " + age + " | " + roll);
}
}
Production Implementation (Clean OOP Architecture)
// Blueprint Class Definition
class Student {
// Member State Fields
String name;
int age;
int rollNumber;
String college;
// Member Behavior Method
void markAttendance() {
System.out.println("Attendance marked by " + name);
}
// Self-Printing Behavior Method
void printDetails() {
System.out.println(name + ", " + age + ", " + rollNumber + ", " + college);
}
}
// Application Entry Class
public class Demo {
public static void main(String[] args) {
// Instantiate Object 1
Student s1 = new Student();
s1.name = "Aditya";
s1.age = 28;
s1.rollNumber = 1001;
s1.college = "IIT Guwahati";
// Instantiate Object 2
Student s2 = new Student();
s2.name = "Rohit";
s2.age = 28;
s2.rollNumber = 102;
s2.college = "IIT Guwahati";
// Invoke Instance Behaviors
s1.markAttendance();
s2.markAttendance();
System.out.println("--- Student Payloads ---");
s1.printDetails();
s2.printDetails();
}
}
12. Deconstructing the Java Main Class Structure
Every Java application requires a wrapper class around its entry point (main method).
public class Demo {
public static void main(String[] args) {
// Execution control enters here
}
}
Why Java is Considered "Almost Purely Object-Oriented"
In Java, no standalone function or variable can exist outside of a class context.
- Even the application execution entry point
main()must be encapsulated inside a class (e.g.,public class Demo). - Unlike languages like C++ or Python—where functions can exist independently at global scope—Java forces all logical routines to reside inside classes.
- It is described as almost purely object-oriented (rather than 100% pure) primarily because it retains primitive data types (
int,char,boolean) for memory performance, rather than forcing everything to be an object wrapper.
Summary and Key Takeaways
- Solving Variable Proliferation: Classes eliminate unstructured variable floating by bundling related attributes into unified custom data containers.
- Selective Domain Modeling (Abstraction): Real-world entities have endless attributes; software classes capture only the properties needed to solve the specific target problem.
- Classes vs. Objects: A
classis an unallocated memory blueprint defining structural design. Anobjectis an active memory instance generated dynamically in the Heap. - Dynamic Memory Allocation (
new): Thenewkeyword allocates object space dynamically inside Heap memory at runtime rather than compile-time. - Stack-to-Heap Reference Architecture: Reference variables reside inside Stack memory execution frames and store physical memory addresses pointing to unnamed actual objects in Heap memory.
- Dot Operator Navigation: The
.operator dereferences the address held in a reference variable, allowing programs to access or update specific object fields and run object methods. - Encapsulation of State and Behavior: Methods placed inside classes operate directly on member fields, removing the need to pass individual fields as method parameters.
- Extensibility to Digital Entities: OOP models physical entities (like
StudentorAnimal) as well as non-physical concepts (likeBankAccountorLocation).