Study guide

3.3 Inheritance, Method Overriding, Polymorphism, and `super`/`this`

Oracle Java SE 17 Developer Certified Professional 1Z0-829

Track your progress as you read

Finished sections get a check mark.

1 Introduction: The 1Z0-829 Exam

About the Java SE 17 Developer (1Z0-829) Exam

2 Chapter 1: Java Fundamentals & Language Basics

1.1 Primitive Types, Literals, Wrapper Classes, and Type Promotion/Casting 1.2 Local Variable Type Inference (`var`) Rules and Scoping 1.3 Operators, Precedence, Evaluation Order, and Short-Circuit Evaluation 1.4 Text Blocks, String Immutability, and StringBuilder APIs

3 Chapter 2: Program Flow & Decision Constructs

2.1 Conditional Branching with if/else and the Ternary Operator 2.2 Switch Statements and Switch Expressions 2.3 Iteration Constructs, Loop Control, and Branching Labels

4 Chapter 3: Object-Oriented Design & Class Mechanics

3.1 Class Declarations, Field/Method Signatures, and Access Modifiers 3.2 Constructors, Overloading, Initialization Order, and Garbage Collection 3.3 Inheritance, Method Overriding, Polymorphism, and `super`/`this` 3.4 Abstract Classes, Static Members, and Object Methods (`equals`, `hashCode`, `toString`)

5 Chapter 4: Advanced OOP: Interfaces, Records & Sealed Types

4.1 Interface Architecture: Default, Static, and Private Methods 4.2 Enumerations: Constants, Constructors, Methods, and Custom Bodies 4.3 Records: Canonical/Compact Constructors, Components, and Immutability 4.4 Sealed Classes and Interfaces: `permits`, Hierarchy Constraints, and Modifiers

6 Chapter 5: Pattern Matching & Nested Types

5.1 Pattern Matching for `instanceof` and Flow Scoping Mechanics 5.2 Nested Types: Member Inner, Static Nested, Local, and Anonymous Classes 5.3 Defensive Programming, Immutability Patterns, and Validation

7 Chapter 6: Generics, Collections & Arrays

6.1 Generic Classes, Interfaces, Methods, and Type Erasure 6.2 Bounded Type Parameters and Wildcards (PECS Rule) 6.3 Collections Framework: List, Set, Queue, and Deque APIs 6.4 The Map Interface, Sorting, Comparable, and Comparator 6.5 Arrays: Declaration, Initialization, Multidimensional Arrays, and the Arrays Utility Class

8 Chapter 7: Functional Programming & Lambda Expressions

7.1 Functional Interfaces and Lambda Syntax Rules 7.2 Standard Functional Interfaces in `java.util.function` 7.3 Method References: Static, Bound, Unbound, and Constructor References

9 Chapter 8: The Stream API

8.1 Stream Lifecycle: Creation, Pipeline Architecture, and Lazy Evaluation 8.2 Intermediate Stream Operations: Filtering, Mapping, Sorting, and Slicing 8.3 Terminal Stream Operations: Reduction, Matching, Finding, and Collecting 8.4 Primitive Streams (`IntStream`, `LongStream`, `DoubleStream`) and Numeric Statistics

10 Chapter 9: Advanced Streams & Collectors

9.1 The Optional Class: Safe Null Handling, Transformation, and Chaining 9.2 The Collectors API: Downstream Reductions, Grouping, and Partitioning 9.3 Parallel Streams: Fork/Join Pool, Spliterators, and Concurrency Pitfalls

11 Chapter 10: Exception Handling

10.1 The Java Exception Hierarchy: Checked vs. Unchecked Exceptions and Errors 10.2 Exception Constructs: `try-catch-finally`, Multi-Catch, and Rethrowing 10.3 Try-With-Resources, `AutoCloseable`, Suppressed Exceptions, and Custom Exceptions

12 Chapter 11: Date/Time API & Localization

11.1 Date and Time Core Types: `LocalDate`, `LocalTime`, `LocalDateTime` 11.2 Timestamps, Intervals, and Durations: `Instant`, `Period`, and `Duration` 11.3 Time Zones, Daylight Saving Time (DST) Offsets, and `ZonedDateTime` 11.4 Internationalization and Localization: `Locale`, `ResourceBundle`, and Formatters 11.5 Formatting and Parsing Messages, Numbers, Percentages, and Localized Dates

13 Chapter 12: Java Platform Module System (JPMS)

12.1 Module Architecture, `module-info.java`, and Module Paths 12.2 Module Directives: `requires`, `requires transitive`, `exports`, and Qualified Exports 12.3 Reflection, Deep Encapsulation, `opens`, and Open Modules 12.4 Services in JPMS (`uses`, `provides...with`), Migration Paths, and Tooling (`jlink`, `jdeps`) 12.5 Compiling and Packaging Code: Non-Modular JARs, Modular JARs, and Migration Strategies

14 Chapter 13: Concurrency & Multithreading

13.1 Thread Fundamentals, `Runnable`, `Callable`, and Thread Lifecycle 13.2 Memory Visibility, `volatile`, Intrinsic Locks, and Synchronization 13.3 The Concurrency Framework: `ExecutorService`, Thread Pools, and `Future` 13.4 Concurrent Collections, Atomic Variables, Explicit Locks, and `CompletableFuture`

15 Chapter 14: Java I/O and NIO.2

14.1 Classical I/O: Byte and Character Streams, Readers, Writers, and Buffering 14.2 Object Serialization, `Serializable`, `transient`, and `serialVersionUID` 14.3 NIO.2 Architecture: `Path`, `Paths`, and Basic `Files` Operations 14.4 Advanced NIO.2: Directory Walking, Streams (`Files.lines`, `walk`), and `WatchService`

16 Chapter 15: Accessing Databases with JDBC

15.1 JDBC Architecture, Drivers, `DriverManager`, and `DataSource` Connections 15.2 SQL Execution: `Statement`, `PreparedStatement`, and `CallableStatement` 15.3 `ResultSet` Navigation, Data Types, and Transaction Management (Commit, Rollback, Savepoints)

17 Chapter 16: Annotations & the Java Logging API

16.1 Standard Annotations: @Override, @FunctionalInterface, @Deprecated, @SuppressWarnings, and @SafeVarargs 16.2 Java Logging API Basics: Logger, Levels, Handlers, and Configuration

3.3 Inheritance, Method Overriding, Polymorphism, and `super`/`this`

Key Takeaways Explain This Topic AI

Java enforces single class inheritance via extends; all classes ultimately inherit from java.lang.Object.

Method overriding requires matching method signatures, covariant return types, same or broader accessibility, and compatible (equal, narrower, or fewer) checked exceptions.

Static methods are not polymorphic; a subclass declaring a static method matching a superclass static method hides the superclass method, resolved by compile-time reference type.

Fields are never polymorphic in Java; variable access is bound at compile time based on the declared reference type, whereas instance method execution is dynamically dispatched at runtime.

Casting references checks class hierarchy compatibility at compile time; runtime type incompatibility throws ClassCastException.

Last updated: October 2026

Inheritance, Method Overriding, and Polymorphism

Inheritance and polymorphism are the structural pillars of object-oriented design in Java. Polymorphism allows an object to take many forms, enabling developers to write extensible code that operates on generalized supertypes while executing specialized subclass behavior at runtime.

1. Single Inheritance and the Object Hierarchy

In Java, a class can extend at most one direct superclass using the extends keyword. Java does not support multiple class inheritance of state or implementation. If a class declaration does not contain an explicit extends clause, the Java compiler automatically inserts extends java.lang.Object . public class Asset {} // Implicitly: public class Asset extends java.lang.Object

  • public class RealEstate extends Asset {} // Directly extends Asset, indirectly extends Object
  • The final Class Barrier

Declaring a class with the final modifier prevents any subclassing. Attempting to extend a final class generates a compile-time error: cannot inherit from final ClassName .

2. Method Overriding Rules (The Five Core Constraints)

Method overriding enables a subclass to provide a specific implementation of an instance method already declared in its superclass. An overriding method must satisfy five strict compiler rules:

Rule 1: Exact Method Signature

The method in the subclass must have the exact same name and identical formal parameter types in the exact same order as the method in the superclass.

Rule 2: Covariant Return Types

The return type of the overriding method must be identical to, or a subtype (covariant) of, the return type declared in the superclass method.

Reference Types : If the superclass returns CharSequence , the subclass may return CharSequence , String , or StringBuilder .

Primitive Types : Covariance does not apply to primitives. If the superclass returns int , the subclass must return int (returning long or Integer is a compile-time error).

Rule 3: Access Modifiers Must Not Be More Restrictive

The overriding method can maintain the same access level or provide broader access, but it cannot restrict access ( public > protected > package-private > private ).

A protected method can be overridden as protected or public .

A package-private method can be overridden as package-private, protected , or public .

A public method can only be overridden as public .

Rule 4: Exception Handling (Checked Exceptions)

The overriding method cannot declare new or broader checked exceptions than those declared in the superclass method throws clause.

The subclass method may declare fewer checked exceptions.

The subclass method may declare subclasses (narrower) of the declared checked exceptions.

The subclass method may omit the throws clause entirely.

Unchecked Exceptions : RuntimeException and Error are unconstrained; an overriding method can declare any unchecked exception regardless of the superclass method signature.

Rule 5: Cannot Override static or final Methods

A method declared final in the superclass cannot be overridden.

private methods are not inherited by subclasses. Defining a method with the same signature in a subclass is considered a brand new method declaration, not an override (placing @Override on it triggers a compile error). class Vehicle {

  • protected Number getSpeed() throws java.io.IOException {
  • return 50;
  • }
  • }
  • class SportsCar extends Vehicle {
  • @Override
  • public Integer getSpeed() throws java.io.FileNotFoundException { // Valid override
  • return 150;
  • }
  • }
  • 3. Method Hiding vs. Method Overriding

Static methods belong to the class, not instance objects, and therefore cannot be overridden . When a subclass declares a static method with the same signature as a superclass static method, it is called method hiding .

  • Feature Method Overriding Method Hiding
  • Method Type Instance methods ( non-static ) Class methods ( static )
  • Dispatch Mechanism Dynamic (runtime actual object type) Static (compile-time declared reference type)
  • Polymorphic Yes No
  • Annotation Supports @Override Cannot use @Override

Warning

A static method cannot hide an instance method, and an instance method cannot override a static method. If one is declared static and the other is not, the compiler flags an error: static method cannot hide instance method or instance method cannot override static method .

4. Field Hiding (Variables Are Not Polymorphic)

In Java, fields are never polymorphic . If a subclass declares a field with the exact same name as a field in its superclass, the subclass field hides the superclass field.

Which field is accessed depends entirely on the declared type of the reference variable , evaluated at compile time, rather than the runtime object on the heap. class Parent {

  • String name = "ParentField";
  • static void log() { System.out.print("ParentStatic "); }
  • void print() { System.out.print("ParentInstance "); }
  • }
  • class Child extends Parent {
  • String name = "ChildField";
  • static void log() { System.out.print("ChildStatic "); }
  • void print() { System.out.print("ChildInstance "); }
  • }
  • public class DispatchDemo {
  • public static void main(String[] args) {
  • Parent ref = new Child();
  • System.out.print(ref.name + " | "); // Evaluates to "ParentField" (Reference type determines field!)
  • ref.log(); // Evaluates to "ParentStatic " (Static method resolved by ref!)
  • ref.print(); // Evaluates to "ChildInstance " (Dynamic method dispatch!)
  • }
  • }

Output of the above code: ParentField | ParentStatic ChildInstance .

5. Polymorphism and Dynamic Method Dispatch

Dynamic method dispatch is the mechanism by which a call to an overridden instance method is resolved at runtime rather than compile time.

When ref.print() is executed:

At compile time , the compiler verifies that the declared reference type ( Parent ) contains an accessible method named print() with matching arguments.

At runtime , the JVM checks the actual object on the heap ( new Child() ), inspects its virtual method table (vtable), and executes Child.print() .

Using super and this

this.method() : Executes the method using normal dynamic dispatch, beginning the resolution check at the current runtime class.

super.method() : Explicitly instructs the JVM to bypass the current class's implementation and invoke the immediate superclass's version of the method.

6. Reference Casting Mechanics and ClassCastException

Reference casting changes the compile-time type of a reference, altering what members are visible to the compiler.

Upcasting (Implicit & Always Safe)

Upcasting moves up the inheritance hierarchy (from subclass to superclass or interface). Because a Child is-a Parent , upcasting is always type-safe and performed automatically by the compiler: Child c = new Child();

  • Parent p = c; // Implicit upcasting
  • Downcasting (Explicit & Potential Runtime Risk)

Downcasting moves down the inheritance hierarchy (from superclass to subclass). Because a Parent reference might not actually hold a Child instance on the heap, downcasting requires an explicit cast operator: Parent p = new Child();

  • Child c = (Child) p; // Explicit downcasting: succeeds because p points to Child
  • Compiler Verification vs. Runtime Verification

Compile-Time Check : The compiler checks if the reference type and the target cast type reside in the same inheritance tree. If the two types are unrelated classes, compilation fails immediately with incompatible types . Casts to an interface type usually compile, because some subclass could implement the interface; the exception is a final class that does not implement it, which the compiler rejects.

Runtime Check : The JVM inspects the heap object. If the actual object is not an instance of the target type (or one of its subtypes), the JVM aborts and throws ClassCastException . class Bird {}

  • class Eagle extends Bird {}
  • class Ostrich extends Bird {}
  • public class CastDemo {
  • public static void main(String[] args) {
  • Bird b = new Eagle();
  • Eagle e = (Eagle) b; // SUCCESS: b points to an Eagle

Ostrich o = (Ostrich) b; // COMPILES, but throws ClassCastException at runtime!

  • // String s = (String) b; // COMPILE ERROR: inconvertible types (Bird and String are unrelated)
  • }
  • }