Classes/Objects  «Prev  Next»


Lesson 1

Classes, Interfaces, and Objects in Java

One of Java's strengths is its excellent support for object-oriented programming. This support is provided through classes and interfaces, which are the building blocks of all Java programs. The ability to effectively use classes and interfaces is an essential Java programming skill. The OCP Java SE 21 certification exam recognizes the importance of class and interface fundamentals and contains a substantial number of questions that test your knowledge of them. This module reviews these topics, introduces modern class forms added in Java 8 through Java 25, and identifies the key points you need to know in preparation for the exam.

In Java, classes, interfaces, and objects are the three pillars of the object-oriented programming paradigm. They each play distinct roles and have specific relationships with one another. Understanding how they interact is foundational to both effective Java development and certification success.

Classes

A class is a blueprint for creating objects. It defines the data (fields) and behaviors (methods) that objects created from the class will have. Every Java program consists of at least one class.


public class Animal {
    String name;
    int age;

    void makeSound() {
        System.out.println("Animal sound");
    }
}

In modern Java, not every data-holding class needs to be written in this verbose form. Java 16 introduced records as a special-purpose class form for immutable data carriers. A record automatically generates a canonical constructor, accessor methods, equals(), hashCode(), and toString():


public record Point(int x, int y) { }

A Point record replaces what would otherwise require a full class with two fields, a constructor, two getters, and three overridden Object methods. Records are final by default and cannot extend other classes, though they may implement interfaces.

Java 17 introduced sealed classes, which restrict which classes may extend or implement them using the permits clause. Sealed classes work well with pattern matching and exhaustive switch expressions introduced in later Java versions:


public sealed interface Shape permits Circle, Rectangle, Triangle { }

public record Circle(double radius) implements Shape { }
public record Rectangle(double width, double height) implements Shape { }
public record Triangle(double base, double height) implements Shape { }

The compiler enforces that only the permitted subtypes exist, enabling exhaustive pattern matching without a default branch.

Interfaces

An interface is a reference type that defines a contract that implementing classes must fulfill. Interfaces cannot contain instance fields or constructors. Prior to Java 8, interfaces could contain only abstract method signatures and constants. Java 8 and later versions significantly expanded what interfaces can contain:

  • Abstract methods - method signatures that implementing classes must override
  • Default methods (Java 8+) - methods with a default implementation, allowing interface evolution without breaking existing implementations
  • Static methods (Java 8+) - utility methods that belong to the interface itself, not to implementing classes
  • Private methods (Java 9+) - shared implementation helpers used internally by default and static methods within the interface
  • Constants - fields that are implicitly public static final


public interface AnimalBehavior {
    // Abstract method - must be implemented
    void makeSound();

    // Default method - Java 8+
    default void breathe() {
        System.out.println("Inhale. Exhale.");
    }

    // Static utility method - Java 8+
    static AnimalBehavior silent() {
        return () -> { };
    }

    // Private helper - Java 9+
    private void logBehavior(String action) {
        System.out.println("Behavior: " + action);
    }
}

Interfaces provide the primary mechanism for achieving abstraction and multiple inheritance of type in Java. A class may implement any number of interfaces simultaneously, which is not possible with class inheritance where only a single superclass is permitted.

Objects

An object is an instance of a class. It is created based on the structure and behavior defined by the class blueprint. Objects are created using the new keyword, which allocates heap memory and invokes the class constructor:


public class Dog extends Animal implements AnimalBehavior {
    @Override
    public void makeSound() {
        System.out.println("Bark");
    }
}

public class Main {
    public static void main(String[] args) {
        Dog myDog = new Dog();
        myDog.name = "Buddy";
        myDog.age = 5;
        myDog.makeSound();
        myDog.breathe();
    }
}

Java 10 introduced local variable type inference using the var keyword. The compiler infers the declared type from the initializer expression, reducing verbosity without losing static typing:


var myDog = new Dog(); // inferred as Dog
var point  = new Point(3, 4); // inferred as Point

var may only be used for local variables with an initializer. It is not permitted for fields, method parameters, or return types.

Relationship Between Classes, Interfaces, and Objects

  1. Classes and Objects - classes define the structure and behavior that objects will have. Objects are instances of classes, created using the new keyword or factory methods.
  2. Classes and Interfaces - a class can implement one or more interfaces, agreeing to fulfill the contract defined by those interfaces. When a class implements an interface, it must provide concrete implementations for all abstract methods declared in the interface unless the class is itself abstract.
  3. Objects and Interfaces - objects created from classes that implement interfaces can be referenced using the interface type. This enables polymorphism, where a single interface type can refer to objects of different implementing classes:

AnimalBehavior b1 = new Dog();
AnimalBehavior b2 = AnimalBehavior.silent();
b1.makeSound(); // Bark
b2.makeSound(); // silent - no output

Sealed interfaces narrow the set of permitted implementations, making the polymorphic type hierarchy explicit and verifiable at compile time.

Classes and Interfaces in Application Design

Classes and interfaces are the building blocks of every Java application. Effective class design has a significant impact on overall application quality. Poor design decisions compound over time: failing to override hashCode() and equals() correctly causes objects to behave unexpectedly in collections such as HashSet and HashMap. Incorrect access modifiers expose internal state to unwanted manipulation from other packages. Poorly designed method signatures make APIs difficult to use and extend.

This module covers the following topics, each of which appears on the OCP Java SE 21 certification exam:

  1. Access modifiers: public, protected, package-private, and private
  2. Method overloading and method overriding
  3. Virtual method invocation and runtime polymorphism
  4. Use of the instanceof operator, pattern matching for instanceof (Java 16+), and casting
  5. Overriding Object methods: equals(), hashCode(), and toString()
  6. Packages, modules (Java 9+), and cross-package class access
  7. Records as immutable data carriers (Java 16+)
  8. Sealed classes and interfaces (Java 17+)
  • Module Objectives
    This module reviews your knowledge of Java classes and interfaces, provides examples of their use in modern Java, and helps you satisfy the following OCP Java SE 21 exam objectives:
    1. Declare classes including top-level, inner, static nested, local, anonymous, sealed, and record classes, making appropriate use of all permitted modifiers.
    2. Identify correctly constructed class declarations of all forms, interface declarations, and their implementations, including sealed hierarchies.
    3. State the benefits of encapsulation in object-oriented design and write tightly encapsulated classes using records where appropriate, demonstrating the "is a" and "has a" relationships.
    4. Write code to construct instances of any concrete class, including normal top-level classes, inner classes, static inner classes, anonymous inner classes, and records using compact constructors.
    5. For a given class, determine if a default constructor will be created, and if so, state the prototype of that constructor, including the implicit canonical constructor generated for records.
    6. Implement interfaces including default methods, static methods, and private methods, and understand the rules governing method resolution when a class implements multiple interfaces with conflicting defaults.

Anonymous Inner Class Question

Anonymous inner classes always extend directly from the Object class.

  1. True
  2. False
Answer: b
Explanation:

When you create an anonymous class that implements an interface, it implicitly extends Object. However, when you create an anonymous class from another class, it extends that class directly. In modern Java, anonymous classes implementing a single-abstract-method (SAM) interface are typically replaced by lambda expressions since Java 8:


// Anonymous class - still valid in all Java versions
Runnable r1 = new Runnable() {
    public void run() {
        System.out.println("anonymous class");
    }
};

// Lambda - preferred in modern Java for SAM interfaces
Runnable r2 = () -> System.out.println("lambda");

Both are valid. The anonymous class is a distinct class that implicitly extends Object and implements Runnable. The lambda is not a class instance - it is a functional interface implementation handled by the JVM's invokedynamic instruction. When an anonymous class extends an existing class rather than implementing an interface, it extends that class directly:


class BaseGreeter {
    public void greet() {
        System.out.println("Hello from BaseGreeter");
    }
}

// Anonymous class extending BaseGreeter - NOT extending Object
BaseGreeter g = new BaseGreeter() {
    @Override
    public void greet() {
        System.out.println("Hello from anonymous subclass");
    }
};

This anonymous class extends BaseGreeter, not Object directly, making the statement false.


SEMrush Software