Study guide

3.3 Inheritance, Method Overriding, and Polymorphism

Oracle Java SE 21 Developer 1Z0-830

Track your progress as you read

Finished sections get a check mark.

1 Chapter 1: Java Basics, Primitive Types, and Operators

1.1 Program Structure, Primitives, Literals, Scopes, and var 1.2 Operators, Precedence, and Type Casting 1.3 Strings, Text Blocks, and StringBuilder 1.4 Date and Time APIs (java.time)

2 Chapter 2: Controlling Program Flow & Pattern Matching

2.1 Conditional Logic: if-else and Ternary Operators 2.2 Switch Statements and Switch Expressions 2.3 Pattern Matching for switch and instanceof 2.4 Loops and Branching Statements

3 Chapter 3: Object-Oriented Design & Class Architecture

3.1 Class Declarations, Constructors, and Object Lifecycle 3.2 Encapsulation and Access Modifiers 3.3 Inheritance, Method Overriding, and Polymorphism 3.4 Abstract Classes and Interfaces 3.5 Nested, Inner, Local, and Anonymous Classes 3.6 Method Overloading, Overload Resolution, and Varargs

4 Chapter 4: Modern Java Data Modeling: Records, Enums, and Sealed Types

4.1 Java Records, Canonical/Compact Constructors, and Component Accessors 4.2 Java Enums: Fields, Methods, and Abstract Constant-Specific Behavior 4.3 Sealed Classes and Interfaces: permits, final, non-sealed, and Hierarchy Architecture 4.4 Advanced Record Patterns (JEP 440), Nested Deconstruction, and Sealed Hierarchy Exhaustiveness

5 Chapter 5: Exception Handling and Annotations

5.1 Exception Hierarchy: Checked vs. Unchecked Exceptions 5.2 Exception Handling: try, catch, finally, and Multi-Catch 5.3 Resource Management: try-with-resources and AutoCloseable 5.4 Custom Exceptions and Best Practices 5.5 Java Annotations: Built-in, Meta-Annotations, and Custom Types

6 Chapter 6: Generics and the Collections Framework

6.1 Generics Fundamentals and Generic Methods 6.2 Wildcards, Type Bounds, and Type Erasure 6.3 Core Collections: Lists, Sets, Queues, and Maps 6.4 Sequenced Collections in Java 21 6.5 Sorting, Comparable, and Comparator 6.6 Arrays: Creation, Multidimensional Forms, and the Arrays Utility Class

7 Chapter 7: Functional Programming & Lambda Expressions

7.1 Built-in Functional Interfaces in java.util.function 7.2 Lambda Expressions, Variable Scopes, and Effectively Final 7.3 Method References: Four Varieties and Edge Cases 7.4 Working with java.util.Optional

8 Chapter 8: The Stream API and Data Pipelines

8.1 Stream Creation and Intermediate Operations 8.2 Terminal Operations and Reductions 8.3 Advanced Collectors, Grouping, Partitioning, and Teeing 8.4 Primitive Streams and Parallel Stream Processing

9 Chapter 9: Concurrency, Multithreading, and Virtual Threads

9.1 Thread Fundamentals, Creation, and Lifecycle 9.2 Thread Safety, Synchronization, and the Java Memory Model 9.3 Concurrency Utilities: ExecutorService, Callable, and Future 9.4 Concurrent Collections, Atomics, and Explicit Locks 9.5 Virtual Threads in Java 21 (Carrier Threads, Pinning, and Best Practices)

10 Chapter 10: The Java Platform Module System (JPMS)

10.1 Module Architecture and module-info.java Declarations 10.2 Module Directives: requires, exports, opens, provides, and uses 10.3 Modular Compilation, Packaging, and CLI Execution 10.4 Module Types, Migration Strategies, ServiceLoader SPI, and JLink

11 Chapter 11: Java I/O, NIO.2, and Object Serialization

11.1 Classic Java I/O Streams and Readers/Writers 11.2 Java NIO.2 File API: Path, Paths, and File System Operations 11.3 Advanced NIO.2 Stream Operations and Directory Traversal 11.4 Java Object Serialization and Record Serialization

12 Chapter 12: Implementing Localization and Internationalization

12.1 Locales and Resource Bundles 12.2 Formatting and Parsing Numbers, Currencies, Dates, Times, and Messages

3.3 Inheritance, Method Overriding, and Polymorphism

Key Takeaways Explain This Topic AI

Method overriding requires matching method signatures, equal or broader access privilege, covariant return types, and no new or broader checked exceptions.

Virtual method invocation resolves instance method calls dynamically at runtime based on the actual object type in heap memory.

Static methods cannot be overridden; re-declaring a static method with the same signature in a subclass hides the parent static method based on reference type.

Fields and static members are bound at compile time based on the reference type and do not participate in polymorphic dispatch.

Last updated: September 2026

Inheritance, Method Overriding, and Polymorphism

Inheritance and polymorphism are the dual cornerstones of object-oriented design in Java SE 21. Inheritance enables subclasses to inherit state and behavior from an ancestor class using extends , while polymorphism enables uniform interaction with diverse object implementations through Dynamic Method Dispatch (Virtual Method Invocation) .

Single Inheritance and Member Propagation

Java enforces single class inheritance : a class can directly extend at most one superclass. If no extends clause is declared, the class implicitly extends java.lang.Object .

What Is Inherited vs. What Is Not

Inherited Members : Subclasses inherit all public and protected fields and methods. Subclasses in the same package also inherit package-private fields and methods.

Non-Inherited Members :

Constructors : Constructors are never inherited; subclasses must declare their own constructors and chain to superclass constructors via super(...) .

Private Members : Private fields and methods are not inherited (they exist in the object state in memory, but are inaccessible by name in the subclass body).

Static Members : Static members are accessible via class inheritance, but they do not participate in polymorphism; static methods are hidden , not overridden.

The Six Strict Rules of Method Overriding

When a subclass declares an instance method intended to override a superclass instance method, it must satisfy all six rules of the Java Language Specification (JLS §8.4.8): class StorageException extends Exception {}

class DiskFullException extends StorageException {}

  • class DataRepository {
  • protected CharSequence loadRecord(String key) throws StorageException {
  • return "Generic Data: " + key;
  • }
  • }
  • class SqlDataRepository extends DataRepository {
  • // 1. Identical Signature: loadRecord(String)
  • // 2. Broader Access: public >= protected
  • // 3. Covariant Return: String is a subtype of CharSequence
  • // 4. Narrower Checked Exception: DiskFullException is a subtype of StorageException
  • @Override
  • public String loadRecord(String key) throws DiskFullException {
  • return "SQL Data: " + key;
  • }
  • }
  • Breakdown of the Six Overriding Rules

Exact Signature Match : The method name and the ordered parameter type list must be identical. Altering parameter types (e.g., loadRecord(CharSequence key) ) creates an overloaded method rather than an overriding method.

Equal or Broader Access Privilege : The overriding method cannot reduce visibility.

public in superclass → \rightarrow → must be public in subclass.

protected in superclass → \rightarrow → can be protected or public .

Package-private in superclass → \rightarrow → can be package-private, protected , or public .

private methods cannot be overridden; defining a method with the same signature in a subclass creates a completely new, unrelated method.

Covariant Return Types : The return type of the overriding method must be identical to, or a subtype of, the return type declared in the superclass method.

Reference Types : Subtypes are permitted (e.g., String overrides CharSequence , ArrayList overrides List ).

Primitive Types : Primitive return types must match identically . You cannot substitute long for int or autobox Integer for int .

Checked Exception Broadening Restrictions : The overriding method cannot declare new or broader checked exceptions . It may declare:

  • Exactly the same checked exceptions,
  • Narrower subclasses of the declared checked exceptions,
  • Fewer checked exceptions (or omit throws entirely),

Any unchecked exceptions ( RuntimeException , Error , or their subclasses).

Instance vs. Static Consistency : An instance method cannot override a static method (compile error), and a static method cannot hide an instance method (compile error).

Non-Final Superclass Method : A method marked final in a superclass cannot be overridden. Attempting to override a final method generates a compile-time error.

Dynamic Method Dispatch (Virtual Method Invocation) vs. Method Hiding

Understanding how the JVM resolves instance method calls versus static method calls is one of the most critical topics on the 1Z0-830 exam. class Vehicle {

  • public static void announce() {
  • System.out.println("Static Vehicle Announcement");
  • }
  • public void startEngine() {
  • System.out.println("Vehicle engine roaring");
  • }
  • }
  • class SportsCar extends Vehicle {
  • // HIDES Vehicle.announce()
  • public static void announce() {
  • System.out.println("Static SportsCar Announcement");
  • }
  • // OVERRIDES Vehicle.startEngine()
  • @Override
  • public void startEngine() {
  • System.out.println("SportsCar V8 engine roaring");
  • }
  • }
  • Execution Behavior and Resolution public class PolymorphismDemo {
  • public static void main(String[] args) {
  • Vehicle v = new SportsCar();
  • // STATIC METHOD HIDING: Resolved at COMPILE TIME based on Reference Type (Vehicle)
  • v.announce(); // Prints: "Static Vehicle Announcement"
  • // INSTANCE METHOD VMI: Resolved at RUNTIME based on Actual Object Type (SportsCar)
  • v.startEngine(); // Prints: "SportsCar V8 engine roaring"
  • }
  • }
  • Dimension Method Overriding (Instance Methods) Method Hiding (Static Methods)
  • Invocation Mechanism Virtual Method Invocation ( invokevirtual ) Static Method Binding ( invokestatic )
  • Resolution Timing Runtime (evaluates heap object type) Compile-time (evaluates declared reference type)
  • Polymorphism Fully polymorphic Non-polymorphic
  • @Override Annotation Required / Recommended Compilation error if applied
  • Field Shadowing and Compile-Time Variable Binding

In Java, fields and variables are NEVER polymorphic . When a subclass declares a field with the same name as a field in its superclass, the subclass field shadows (hides) the superclass field. class BaseSensor {

  • public int reading = 10;
  • public int getReading() { return reading; }
  • }
  • class PrecisionSensor extends BaseSensor {
  • public int reading = 99; // Shadows BaseSensor.reading
  • @Override
  • public int getReading() { return reading; }
  • }
  • public class FieldShadowDemo {
  • public static void main(String[] args) {
  • BaseSensor sensor = new PrecisionSensor();
  • // DIRECT FIELD ACCESS: Bound at compile-time by Reference Type (BaseSensor)
  • System.out.println("Field: " + sensor.reading); // Prints: 10
  • // POLYMORPHIC METHOD: Bound at runtime by Object Type (PrecisionSensor)
  • System.out.println("Method: " + sensor.getReading()); // Prints: 99
  • }
  • }
  • Polymorphic Casting Mechanics and ClassCastException
  • Java supports two categories of reference type casting: class Animal {}
  • class Mammal extends Animal {}
  • class Dog extends Mammal { public void bark() { System.out.println("Woof"); } }
  • class Cat extends Mammal {}
  • public class CastingDemo {
  • public static void main(String[] args) {
  • // 1. UPCASTING: Widening reference conversion (Implicit & always safe)
  • Animal a = new Dog();
  • Mammal m = (Mammal) a; // Explicit upcast is valid but redundant
  • // 2. DOWNCASTING: Narrowing reference conversion (Requires explicit cast)
  • Dog d = (Dog) a; // Valid downcast: 'a' points to Dog instance on heap
  • d.bark();
  • // 3. INVALID DOWNCAST: Compiles but throws ClassCastException at runtime
  • Animal catAnimal = new Cat();
  • // Dog invalidDog = (Dog) catAnimal; // Throws ClassCastException: Cat cannot be cast to Dog
  • // 4. SAFE CASTING: Pattern Matching for instanceof (Java 16+ / 21)
  • if (catAnimal instanceof Dog activeDog) {
  • activeDog.bark(); // Only entered if catAnimal is truly a Dog
  • } else {
  • System.out.println("catAnimal is not a Dog");
  • }
  • }
  • }
  • Compiler vs. Runtime Casting Rules

Unrelated Class Types : The compiler inspects the inheritance hierarchy. If two classes have no ancestor/descendant relationship and cannot possibly reference the same instance, the compiler rejects the cast with an inconvertible types error (e.g., String s = (String) new Dog(); ).

Interface Casting : An explicit cast from a class to an interface will always compile (unless the class is declared final and does not implement the interface), because a subclass could potentially implement the interface at runtime.

Runtime Verification : At runtime, the JVM inspects the actual object type on the heap. If the object does not pass the instanceof check for the target type, a ClassCastException is immediately thrown.

Common 1Z0-830 Exam Traps

Primitive Return Type Mismatch in Overrides : Changing a return type from int to long is NOT a covariant return; it is a compile-time error. Covariant returns only apply to subtype reference types.

Broader Checked Exceptions in Overrides : If the parent throws IOException , the child cannot throw Exception or Throwable . It CAN throw FileNotFoundException or no checked exceptions.

Calling Hidden Static Methods on References : Parent p = new Child(); p.staticMethod(); invokes Parent.staticMethod() , not Child.staticMethod() .

Field Access on Polymorphic Variables : p.field evaluates the field in Parent , even if p points to new Child() and Child defines field .

Loading diagram... Virtual Method Invocation vs Field Shadowing