Fundamentals 11 min read

Understanding Object‑Oriented Programming: Classes, Objects, and Memory in Java

This article explains the core concepts of object‑oriented programming in Java, covering the relationship between classes and objects, the four OOP principles, comparisons with procedural programming, illustrative Gomoku game code, and how Java’s stack and heap memory model underpins references and object instantiation.

Java Captain
Java Captain
Java Captain
Understanding Object‑Oriented Programming: Classes, Objects, and Memory in Java

Object‑Oriented Programming

For beginners of Java or any object‑oriented language, the ideas of class and object can be confusing. This article clarifies the OOP mindset, the meaning of classes and objects, and why OOP aligns better with real‑world thinking.

Everything in the world can be treated as an object; relationships in the real world are abstracted into classes and inheritance, helping us model reality digitally.

Programming should solve real problems, so the programming paradigm should mirror real‑world reasoning. OOP makes code more intuitive and easier to understand, and it applies not only to coding but also to the design phase.

Why OOP Mirrors Real Life

We describe things using HAS‑A (attributes or behaviors) and IS‑A (type). Combining these attributes forms a class , while inheritance captures shared traits and polymorphism captures variations such as oviparity versus viviparity.

The four OOP pillars are:

Abstraction

Encapsulation

Inheritance

Polymorphism

Comparison with Early Structured Programming

Structured (procedural) programming treats a program as a collection of functions, passing data as parameters. In OOP, objects are the primary entities and methods belong to those objects.

For example, a simple Gomoku game can be designed procedurally as a sequence of steps, whereas an OOP design splits the game into player objects, a board object, and a rule (referee) object. The player objects handle input, the board object renders the state, and the referee object decides the outcome.

Below is a lightweight Java implementation illustrating these ideas:

/**
 * Player class
 */
public class Player {
    String name;               // player name
    boolean isFirst;           // is first mover
    int color_flag;            // 0‑white, 1‑black
    Table table;               // reference to board

    public Player(String name, boolean isFirst, int color_flag) {
        this.name = name;
        this.isFirst = isFirst;
        this.color_flag = color_flag;
    }

    /** place a piece at (x, y) */
    public void play(int x, int y) throws Exception {
        if (this.table == null) {
            throw new IllegalArgumentException("Player not registered to a board!");
        }
        table.setNewPieces(x, y);
    }

    public void setTable(Table table) {
        this.table = table;
    }
}

/**
 * Board class
 */
public class Table {
    List
playerList = new ArrayList<>();
    Referee referee;
    public Table() {
        referee = new Referee(this);
    }
    public void registPlayer(Player player) throws Exception {
        // check capacity, first‑player/color conflicts, etc.
        playerList.add(player);
        player.setTable(this);
    }
    public void setNewPieces(int x, int y) {
        // redraw board, then ask referee to evaluate
        if (referee.isEnd()) {
            End();
        }
    }
    public void End() {
        // handle game over
    }
}

/**
 * Referee class
 */
public class Referee {
    Table table;
    public Referee(Table table) {
        this.table = table;
    }
    public boolean isEnd() {
        // determine win/lose
        return false;
    }
}

Class and Object from a Data‑Type Perspective

In Java, primitive types (byte, short, int, long, double, char, boolean) are stored directly, while reference types (including classes, interfaces, arrays, enums, annotations) require the new keyword. The variable holds a reference (memory address) to an object on the heap.

Example:

int a = 1;
Person b = new Person();

Here a is a primitive value, while b is a reference to a Person object allocated on the heap.

Memory Model: Stack vs. Heap

Java splits memory into a stack (for primitive values and references) and a heap (for actual objects). When Person p = new Person(); executes, p holds the heap address of the newly created object.

Conclusion

Object‑oriented programming is not just a coding style but a way of thinking that encompasses analysis, design, and implementation. Objects are the basic units, classes are templates, and encapsulation hides data inside objects. Understanding these concepts, together with Java’s memory model, helps write clearer, more maintainable code.

Javaprogramming fundamentalsoopclassesobjects
Java Captain
Written by

Java Captain

Focused on Java technologies: SSM, the Spring ecosystem, microservices, MySQL, MyCat, clustering, distributed systems, middleware, Linux, networking, multithreading; occasionally covers DevOps tools like Jenkins, Nexus, Docker, ELK; shares practical tech insights and is dedicated to full‑stack Java development.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.