Codectionary / Developer documentation / Java

Classes

Classes in Java are blueprints for creating objects, defining their properties (fields) and behaviors (methods). Java is a strictly object-oriented language where everything is encapsulated within classes. A class serves as a template that specifies what data an object will store and what operations it can perform.

Before you start: Variables & Primitive Data Types

Syntax

public class ClassName {
  // fields and methods
}

Breaking down the syntax

class
Declares a reference type.
field
Stores state belonging to an instance, or to the class when static.
constructor
Initialises a newly created instance.
method
Declares an operation.

How it works

A class describes a type of object: the state it stores and the operations it supports. Each instance has its own instance fields.

Class definition

Declare fields, constructors and methods.

new

Allocate an instance and invoke a constructor.

Object

Call methods through a reference to that instance.

Examples

Create an object

Save as Main.java; compile and run with a JDK.

class Book {
  String title;
  Book(String title) { this.title = title; }
}
public class Main {
  public static void main(String[] args) {
    Book book = new Book("Learning Java");
    System.out.println(book.title);
  }
}
  1. Book describes the type.
  2. The constructor assigns the argument to the instance field.
  3. new Book creates an object.

Encapsulate state

Change private state through a method.

class Counter {
  private int value;
  void increment() { value++; }
  int getValue() { return value; }
}
public class Main {
  public static void main(String[] args) {
    Counter counter = new Counter();
    counter.increment();
    System.out.println(counter.getValue());
  }
}
  1. Each Counter starts with its own value of zero.
  2. increment changes the current instance.
  3. getValue exposes a result without exposing the field.

Validate a constructor input

Construct an object only when its required value is present.

class Lesson {
  private final String title;
  Lesson(String title) {
    if (title == null || title.isEmpty()) {
      throw new IllegalArgumentException("Title is required");
    }
    this.title = title;
  }
  String getTitle() { return title; }
}
public class Main {
  public static void main(String[] args) {
    System.out.println(new Lesson("Classes").getTitle());
  }
}
  1. The constructor rejects null and empty strings.
  2. The final field is assigned once by the constructor.
  3. The getter returns the validated title.

Basic Class

Creating a simple class with fields and methods.

public class Person {
  // Fields
  private String name;
  private int age;
  
  // Constructor
  public Person(String name, int age) {
    this.name = name;
    this.age = age;
  }
  
  // Getter methods
  public String getName() {
    return name;
  }
  
  public int getAge() {
    return age;
  }
  
  // Method
  public void introduce() {
    System.out.println("Hi, I'm " + name + " and I'm " + age + " years old.");
  }
}

// Usage
Person person = new Person("Alice", 25);
person.introduce();

Encapsulation

Using private fields with public getters and setters.

public class BankAccount {
  private String accountNumber;
  private double balance;
  
  public BankAccount(String accountNumber, double initialBalance) {
    this.accountNumber = accountNumber;
    this.balance = initialBalance;
  }
  
  public double getBalance() {
    return balance;
  }
  
  public void deposit(double amount) {
    if (amount > 0) {
      balance += amount;
      System.out.println("Deposited: $" + amount);
    }
  }
  
  public void withdraw(double amount) {
    if (amount > 0 && amount <= balance) {
      balance -= amount;
      System.out.println("Withdrawn: $" + amount);
    } else {
      System.out.println("Insufficient funds");
    }
  }
}

// Usage
BankAccount account = new BankAccount("12345", 1000.0);
account.deposit(500.0);
account.withdraw(200.0);
System.out.println("Balance: $" + account.getBalance());

Inheritance

Creating subclasses that extend parent classes.

public class Animal {
  protected String name;
  
  public Animal(String name) {
    this.name = name;
  }
  
  public void makeSound() {
    System.out.println("Some sound");
  }
}

public class Dog extends Animal {
  private String breed;
  
  public Dog(String name, String breed) {
    super(name);  // Call parent constructor
    this.breed = breed;
  }
  
  @Override
  public void makeSound() {
    System.out.println(name + " says: Woof!");
  }
  
  public void fetch() {
    System.out.println(name + " is fetching the ball");
  }
}

// Usage
Dog dog = new Dog("Buddy", "Golden Retriever");
dog.makeSound();
dog.fetch();

Static Members

Using static fields and methods that belong to the class.

public class Counter {
  private static int count = 0;  // Shared across all instances
  private int instanceId;
  
  public Counter() {
    count++;
    this.instanceId = count;
  }
  
  public static int getCount() {
    return count;
  }
  
  public int getInstanceId() {
    return instanceId;
  }
  
  public static void resetCount() {
    count = 0;
  }
}

// Usage
Counter c1 = new Counter();
Counter c2 = new Counter();
Counter c3 = new Counter();

System.out.println("Total instances: " + Counter.getCount());  // 3
System.out.println("c2 ID: " + c2.getInstanceId());  // 2

Best practices

  • Use meaningful class names that describe what the class represents (PascalCase)
  • Keep fields private and provide public getters/setters (encapsulation)
  • Write one class per file, with the filename matching the public class name
  • Use constructors to initialize object state properly
  • Override toString() method for better object debugging
  • Follow the Single Responsibility Principle - each class should have one clear purpose

Runtime & versions

Java Virtual Machine. Feature availability depends on the language and runtime version used by your project; consult the official reference below.

Java Language Specification

When should I use this?

Use a class to model related state and behaviour with clear responsibilities. Prefer small cohesive classes over a single class that manages everything.

Common mistakes

Giving a constructor a return type

A declaration with void is a method, even when its name matches the class.

Incorrect

class Book {
  void Book() { }
}

Corrected

class Book {
  Book() { }
}

Compare approaches

  • Class: Encapsulate state and implementation.
  • Interface: Define a contract that classes can implement.
  • Record: Represent a transparent data carrier when appropriate.

Explore deeper

Instance members and static members

Instance fields belong to each object. A static field belongs to the class. A static method has no current instance and cannot directly access instance members without an object reference.

Access control

Make fields private when callers should use operations rather than modify state directly. Public APIs should express what the object does, not expose every implementation detail.

Specifications & further reading