Object-Oriented Programming Basics

Classes & Objects

15 min Lesson 1 of 14

Classes & Objects

Everything in Java revolves around one central idea: the class. A class is a blueprint — a precise description of what something is and what it can do. An object is a single, live instance of that blueprint. Once you grasp this distinction you hold the key to all of object-oriented programming (OOP).

The Blueprint Analogy

Think of a class as an architectural floor plan for a house. The plan describes every room, door, and window, but it is not a house you can live in — it is just a document. When a builder follows that plan and constructs an actual house, that house is an object. You can build many houses from the same plan; each is independent and can be painted a different colour, but they all share the same structure.

In Java the same logic applies. You write a class once and then instantiate it as many times as you like. Each instance has its own copy of the data, yet they all behave according to the rules defined in the class.

Defining a Class

The simplest possible class in Java looks like this:

public class Dog { // fields (data the object will hold) String name; String breed; int age; // method (behaviour the object can perform) void bark() { System.out.println(name + " says: Woof!"); } }

Breaking this down:

  • public — an access modifier; other classes can see this one.
  • class Dog — the keyword class followed by the name. Java convention: class names start with an uppercase letter and use CamelCase.
  • The curly braces { } mark the body — everything the class owns goes inside.
  • String name, String breed, int age are fields (also called instance variables). They store the state of each individual object.
  • void bark() is a method — a named block of code that objects of this class can execute.
One public class per file. Java requires that a public class has the same name as the file it lives in. So the Dog class above must be saved in a file named Dog.java. This is a compiler rule, not just a convention.

Creating Objects with new

Defining a class creates no data at runtime — it only tells the compiler what a Dog looks like. To bring a real dog into existence you use the new keyword:

public class Main { public static void main(String[] args) { // create two Dog objects from the same blueprint Dog dog1 = new Dog(); Dog dog2 = new Dog(); // give each object its own data dog1.name = "Rex"; dog1.breed = "Labrador"; dog1.age = 3; dog2.name = "Luna"; dog2.breed = "Poodle"; dog2.age = 5; // each object runs the same method, but uses its own name dog1.bark(); // prints: Rex says: Woof! dog2.bark(); // prints: Luna says: Woof! } }

What happens when you write new Dog()?

  1. Java allocates a block of memory on the heap large enough to hold all the fields of a Dog.
  2. A reference to that memory block is returned and stored in the variable (dog1 or dog2).
  3. The fields start with default values (null for objects, 0 for numbers) until you assign something.
Variables hold references, not objects. When you write Dog dog1 = new Dog(), the variable dog1 does not contain the Dog — it holds an address pointing to the Dog on the heap. This matters when you pass objects to methods or assign one variable to another.

Fields Belong to the Instance

Each object maintains its own independent set of field values. Changing dog1.name has absolutely no effect on dog2.name:

dog1.name = "Max"; // only dog1 is affected System.out.println(dog2.name); // still prints: Luna

This is the essence of instance state: every object lives its own life with its own data.

A Slightly Richer Example

Here is a BankAccount class that introduces a method doing real work:

public class BankAccount { String owner; double balance; void deposit(double amount) { balance = balance + amount; System.out.println("Deposited " + amount + ". New balance: " + balance); } void printSummary() { System.out.println("Account owner: " + owner + ", Balance: " + balance); } }
public class Main { public static void main(String[] args) { BankAccount account = new BankAccount(); account.owner = "Alice"; account.balance = 1000.0; account.deposit(250.0); // Deposited 250.0. New balance: 1250.0 account.printSummary(); // Account owner: Alice, Balance: 1250.0 } }
Direct field access is a stepping stone, not best practice. In these early examples you write account.balance = 1000.0 directly. As the course progresses you will learn encapsulation — hiding fields behind private and controlling access through methods. For now, direct access lets you focus on the class/object concept without extra ceremony.

Why This Matters

Classes and objects let you model the real world directly in code. Instead of juggling parallel arrays of names, breeds, and ages, you have a single Dog type that keeps its data together and knows how to behave. As programs grow, this grouping of state + behaviour into named types is what keeps code readable and maintainable.

Summary

  • A class is a blueprint that defines fields (state) and methods (behaviour).
  • An object is a live instance of a class, created with new ClassName().
  • Each object has its own independent copy of the fields.
  • The variable that holds an object stores a reference (memory address), not the object itself.
  • Class names use UpperCamelCase; a public class must match its filename.