Difficulty: Intermediate | Prerequisites: Java Fundamentals, Operations, Control Flow, and Methods.
Object-oriented programming (OOP) is the organising principle behind almost all Java code. This unit introduces classes, objects, inheritance, polymorphism, and interfaces, along with the access control rules that keep code modular and maintainable. It also covers exception handling (how Java deals with things that go wrong at runtime) and arrays (the simplest way to store collections of data). If you are catching up, make sure you are comfortable with methods, data types, and loops before tackling this material, because OOP builds directly on all three.
A class is a blueprint; an object is an instance of that blueprint. Encapsulation hides internal data behind access modifiers. Inheritance lets one class extend another, and polymorphism lets a superclass reference point to subclass objects. Interfaces define contracts without implementation. Exception handling uses try-catch-finally to deal with runtime errors gracefully. Arrays store fixed-size collections of elements and are processed with common patterns like reduce and filter.
Class
A blueprint that defines a set of attributes (data) and methods (behaviour). A class describes what an object will look like and what it can do, but is not itself an object. Think of it as the architectural plan for a house.
Object
A specific instance of a class, created with the new keyword. Each object has its own copy of the class's attributes. In simple terms, the class is the blueprint, the object is the actual house built from it.
Constructor
A special method with the same name as the class, called automatically when you create an object with new. It initialises the object's attributes. Constructors can take parameters or be no-argument ("default").
Encapsulation
The practice of bundling data and the methods that operate on that data into a single unit (a class), and restricting direct access to the data using access modifiers. This protects internal state from unintended modification.
Access modifiers
Keywords that control visibility: public (accessible from anywhere), protected (accessible within the same package and by subclasses), private (accessible only within the declaring class).
Mutator method (setter)
A method that modifies a private field. Convention: setFieldName(value).
Accessor method (getter)
A method that returns the value of a private field without changing it. Convention: getFieldName().
Inheritance
A mechanism where a new class (subclass) extends an existing class (superclass), inheriting its fields and methods. Declared with the extends keyword. Think of it as a child class that gets everything the parent has, plus its own additions.
Method overriding
Defining a method in a subclass with the same signature as a method in the superclass, replacing the superclass behaviour for objects of the subclass type.
super()
A call to the parent class's constructor or method from within a subclass. Used to reuse parent initialisation logic or invoke the parent's version of an overridden method.
Polymorphism
The ability of a superclass reference variable to point to objects of different subclass types, with the correct overridden method executing based on the actual object at runtime. In simple terms, one variable type, many possible behaviours, depending on which subclass object it holds.
Interface
A contract that specifies method signatures without providing implementations. A class that implements an interface must provide concrete code for every method declared in the interface.
Abstract class
A class that can contain both abstract methods (no body, must be overridden) and concrete methods (with a body). You cannot instantiate an abstract class directly; it serves as a base for subclasses.
Checked exception
An exception that the compiler forces you to handle (with try-catch) or declare (with throws in the method signature). Example: IOException.
Unchecked exception
A runtime exception that does not require explicit handling. Examples: NullPointerException, ArrayIndexOutOfBoundsException.
Finally block
A block that executes after the try-catch, regardless of whether an exception occurred. Commonly used for cleanup, such as closing files or releasing resources.
Array
A fixed-size, ordered collection of elements of the same type. Declared as int[] a = new int[10]; and accessed by index starting at 0.
A class defines attributes (instance variables) and methods. An object is created from a class using new: Dog myDog = new Dog();
Constructors initialise the object. If you do not write a constructor, Java provides a default no-argument constructor. Once you define any constructor, the default disappears unless you explicitly write one.
Fields should generally be private, with public getter and setter methods providing controlled access. This is encapsulation.
public: visible everywhere.
protected: visible within the package and to subclasses in other packages.
private: visible only inside the class that declares the field or method.
Choose the most restrictive modifier that still allows the code to work. Default to private for fields.
Use extends to create a subclass: class Cat extends Pet { ... }
The subclass inherits all non-private fields and methods from the superclass.
A subclass can override inherited methods to provide specialised behaviour. The method signature must match exactly.
Use super() in a subclass constructor to call the parent constructor. If the parent has no no-argument constructor, calling super(args) is mandatory.
A superclass variable can hold a subclass object: Pet p = new Cat();
When you call an overridden method on p, Java executes the Cat version, not the Pet version. This is dynamic method dispatch.
Polymorphism lets you write code that works with the superclass type and handles any subclass transparently.
An interface declares method signatures with no implementation. A class uses implements to adopt the interface and must provide bodies for all declared methods.
Interfaces enforce uniformity: multiple unrelated classes can implement the same interface, guaranteeing they all offer the same set of behaviours.
An abstract class can mix abstract methods (which subclasses must override) with concrete methods (which subclasses inherit as-is). Use an abstract class when subclasses share common code; use an interface when they share a contract but not an implementation.
Exceptions represent error conditions that arise at runtime: file not found, division by zero, null references.
throw new ExceptionType("message") signals that something has gone wrong.
try { ... } catch (ExceptionType e) { ... } wraps risky code and defines what to do if that specific exception occurs.
The finally block runs whether or not an exception was thrown, and is the right place for cleanup tasks.
Checked exceptions (e.g., IOException) must be caught or declared with throws. The compiler enforces this.
Unchecked exceptions (e.g., NullPointerException, ArithmeticException) do not require explicit handling, though you can still catch them.
Compilation errors: syntax mistakes caught before the program runs.
Runtime errors: occur during execution (division by zero, null pointer).
Semantic errors: the program runs but produces incorrect results.
Debugging follows a five-step process: discover, reproduce, isolate, fix, review.
Tools include print statements, IDE debuggers with breakpoints (including conditional breakpoints), and try-catch blocks for graceful error handling.
Declared with a type and size: int[] scores = new int[5];
Elements are accessed by index, starting at 0: scores[0], scores[1], etc.
scores.length gives the number of elements.
Accessing an index outside the valid range throws ArrayIndexOutOfBoundsException.
Map (apply-to-all): apply the same operation to every element, e.g., double each value.
Reduce: aggregate all elements into a single value. Summing, finding the max, or finding the min are classic reduce operations.
Filter: select elements that meet a condition and discard the rest.
int sum = 0;
for (int i = 0; i < array.length; i++) {
sum += array[i];
}
Inheritance hierarchy (typical exam example):
Pet (superclass)
/ \
Cat Dog (subclasses)
A Pet reference can point to a Cat or a Dog. The overridden method in the actual object's class executes at runtime.
Encapsulation is the reason every well-designed API hides its internal data and exposes only what callers need. Inheritance and polymorphism underpin frameworks like Java Swing (where every GUI component extends JComponent) and Android (where every screen extends Activity). Exception handling is essential in any program that deals with files, networks, or user input, where failures are normal rather than exceptional. Arrays are the foundation for more advanced data structures (ArrayLists, hash tables) you will meet later.
Students often confuse method overloading with method overriding. Overloading is same name, different parameters, in the same class. Overriding is same name, same parameters, in a subclass replacing a superclass method.
"Polymorphism" does not mean "inheritance." Inheritance is the mechanism; polymorphism is the behaviour that inheritance enables, specifically dynamic dispatch of overridden methods.
Students sometimes think finally only runs when an exception occurs. It runs always: after the try block if no exception occurs, or after the catch block if one does.
An interface is not the same as an abstract class. An interface (in standard Java SE at this course level) provides no implementation; an abstract class can provide partial implementation.
⚠️ Be able to trace a polymorphism scenario: given a superclass reference holding a subclass object, identify which version of an overridden method executes.
⚠️ Know the three access modifiers and their visibility rules.
⚠️ Understand the difference between checked and unchecked exceptions and when you must use try-catch.
⚠️ Be ready to write or trace a reduce pattern (summing, finding max/min) over an array.
⚠️ Know the five debugging steps: discover, reproduce, isolate, fix, review.
True or false: A private field can be accessed from a subclass.
Fill in the blank: The keyword _______ is used to create a subclass in Java.
True or false: An interface can contain method bodies.
Fill in the blank: array.length returns the _______ of the array.
True or false: The finally block only executes when an exception is thrown.
Answers: 1. False (private fields are not accessible outside the declaring class, even by subclasses). 2. extends. 3. False (at the introductory level covered in this course, interfaces declare method signatures without bodies). 4. Number of elements (size). 5. False (it executes regardless of whether an exception occurred).
Q: What is the difference between method overloading and method overriding?
A: Overloading defines multiple methods with the same name but different parameter lists within the same class. Overriding defines a method in a subclass with the exact same signature as a method in the superclass, replacing the superclass behaviour.
Q: Given Pet p = new Cat(); and both Pet and Cat have a speak() method, which version runs when you call p.speak()?
A: The Cat version. Java uses dynamic method dispatch, selecting the overridden method in the actual object's class at runtime.
Q: What is the purpose of the finally block in exception handling?
A: The finally block contains code that runs after the try (and catch, if triggered) block, regardless of whether an exception occurred. It is typically used for cleanup tasks such as closing files or releasing resources.
Q: Write a loop that finds the maximum value in an integer array called data.
A: int max = data[0]; for (int i = 1; i < data.length; i++) { if (data[i] > max) { max = data[i]; } }
Q: Explain the difference between a checked and an unchecked exception.
A: A checked exception (e.g., IOException) must be caught with try-catch or declared with throws in the method signature; the compiler enforces this. An unchecked exception (e.g., NullPointerException) occurs at runtime and does not require explicit handling.
OOP concepts connect to every later unit. GUI programming uses inheritance (Swing components extend JComponent) and event handling uses interfaces (ActionListener). Exception handling reappears in file I/O and web development. Arrays are the stepping stone to more advanced data structures and algorithms courses. The debugging process covered here applies universally across all programming tasks.
class, object, instance, constructor, new keyword, encapsulation, access modifier, public, private, protected, getter, setter, mutator, accessor, inheritance, extends, subclass, superclass, method overriding, super, polymorphism, dynamic dispatch, interface, implements, abstract class, exception, try-catch, finally, throw, throws, checked exception, unchecked exception, IOException, NullPointerException, array, index, ArrayIndexOutOfBoundsException, map pattern, reduce pattern, filter pattern, debugging, breakpoint, CS 101, Texas A&M