| Study Guides
College Board · cb-cs-a · AP Computer Science A · Inheritance · 16 min read · Updated 2026-05-07

Inheritance — AP Computer Science A CS A Study Guide

For: AP Computer Science A candidates sitting AP Computer Science A.

Covers: Superclass and subclass hierarchies, extends and super keyword usage, method overriding with @Override, polymorphism and IS-A relationships, and introductory abstract classes for AP CS A Unit 9.

You should already know: Basic Java or any other procedural-language programming.

A note on the practice questions: All worked questions in the "Practice Questions" section below are original problems written by us in the AP Computer Science A style for educational use. They are not reproductions of past College Board papers and may differ in wording, numerical values, or context. Use them to practise the technique; cross-check with official College Board mark schemes for grading conventions.


1. What Is Inheritance?

Inheritance is a core object-oriented programming (OOP) mechanism that lets you create new classes from existing classes, reusing shared code, extending functionality, and modeling hierarchical real-world relationships. It eliminates redundant code by centralizing shared attributes and methods in a single parent class, rather than rewriting the same logic across multiple related classes. Per the AP CS A Course and Exam Description, inheritance makes up 10-15% of your total exam score, and is tested in both multiple-choice and free-response questions.

2. Superclass and subclass

A superclass (or parent class) is the existing class that contains shared attributes and methods for all related classes. A subclass (or child class) is a new class that inherits from the superclass, and can add its own unique attributes and methods, or modify inherited methods to suit its specific needs.

A subclass inherits all public and protected members of its superclass, but cannot directly access private superclass members. Java does not support multiple inheritance, so a subclass can only extend one superclass.

Worked Example

Suppose you are building an application for a pet shelter. All pets share attributes like name, age, and methods like eat() and sleep(). Instead of rewriting these for every pet type, you define a superclass Pet:

public class Pet {
 private String name;
 private int age;

 public Pet(String n, int a) {
 name = n;
 age = a;
 }

 public void eat() {
 System.out.println(name + " is eating.");
 }

 // Getters for private attributes
 public String getName() { return name; }
 public int getAge() { return age; }
}

You can then define subclasses Dog and Cat that inherit all shared logic from Pet, without rewriting the name, age attributes or eat() method.

3. extends keyword and super calls

To declare a subclass, use the extends keyword followed by the superclass name:

public class SubclassName extends SuperclassName { /* class code */ }

The super keyword has two key use cases in subclasses:

  1. Call a superclass constructor: super() must be the first line of a subclass constructor. If you do not explicitly write a super() call, Java automatically inserts a no-argument super() call. If your superclass does not have a no-argument constructor, you must explicitly call a parameterized super() to avoid a compile error.
  2. Call an overridden superclass method: Use super.methodName() to access the superclass version of a method that you have overridden in the subclass.

Worked Example

We extend the Pet superclass to create a Dog subclass with a unique breed attribute and bark() method:

public class Dog extends Pet {
 private String breed;

 public Dog(String n, int a, String b) {
 // Call superclass constructor first to initialize shared attributes
 super(n, a);
 breed = b;
 }

 public void bark() {
 System.out.println(getName() + " the " + breed + " barks: Woof!");
 }

 public String getDetails() {
 // Use superclass getter methods for private superclass attributes
 return getName() + " is a " + getAge() + " year old " + breed;
 }
}

If you tried to omit the super(n, a) call, the code would fail to compile: the Pet class has no no-argument constructor, so Java's implicit super() call would not match any existing constructor.

4. Method overriding and @Override

Method overriding occurs when a subclass provides a specific implementation of a method that is already defined in its superclass. For a valid override:

  • The method signature (name, number of parameters, parameter types) must be exactly identical to the superclass method
  • The return type must be compatible with the superclass return type
  • The access modifier cannot be more restrictive than the superclass method (e.g. you cannot override a public method with a private method)

The @Override annotation is optional but highly recommended: it tells the Java compiler you intend to override a superclass method, so it will throw a compile error if you make a typo in the method signature (instead of accidentally creating an unrelated overloaded method).

Worked Example

All pets make sounds, but the sound varies by pet type. We add a makeSound() method to the Pet superclass, then override it in Dog and Cat:

// In Pet superclass
public void makeSound() {
 System.out.println("Generic pet sound");
}

// In Dog subclass
@Override
public void makeSound() {
 System.out.println("Woof!");
}

// In Cat subclass
@Override
public void makeSound() {
 System.out.println("Meow!");
}

AP examiners frequently test the difference between overriding and overloading: overloading uses the same method name with different parameters in the same class, while overriding uses an identical signature in a subclass.

5. Polymorphism — IS-A relationship

Inheritance creates an IS-A relationship between subclasses and superclasses: every subclass instance IS-A type of its superclass. For example, a Dog IS-A Pet, a Cat IS-A Pet, but a Pet is not necessarily a Dog.

Polymorphism (meaning "many forms") leverages this IS-A relationship: a reference variable of a superclass type can refer to an object of any of its subclass types. At runtime, the JVM calls the method version matching the actual object type, not the reference type (this is called runtime polymorphism, the primary form tested on AP CS A).

Worked Example

We can create an array of Pet references that point to Dog and Cat objects:

Pet[] shelterPets = {
 new Dog("Buddy", 3, "Golden Retriever"),
 new Cat("Mittens", 2, "Tabby"),
 new Pet("Generic", 1)
};

for (Pet p : shelterPets) {
 p.makeSound();
}

The output will be:

Woof!
Meow!
Generic pet sound

A common exam trap: you cannot call a subclass-specific method on a superclass reference without casting. For example, shelterPets[0].bark() will throw a compile error, because the Pet reference type has no bark() method. To access the subclass method, cast the reference first: ((Dog) shelterPets[0]).bark(). If you cast to the wrong object type, you will get a ClassCastException at runtime.

6. Abstract classes (intro)

An abstract class is a class that cannot be instantiated (you cannot create a new object of the abstract class directly). It is designed to be a blueprint for subclasses, defining shared attributes and methods that all subclasses must implement. You declare an abstract class with the abstract keyword:

public abstract class ClassName { /* class code */ }

Abstract classes can contain abstract methods: methods with no implementation, only a signature, declared with the abstract keyword. Any concrete (non-abstract) subclass that extends the abstract class must override all abstract methods, or the subclass will also be treated as abstract.

Worked Example

We don't want to create generic Pet objects in our shelter app, so we make Pet an abstract class with an abstract makeSound() method:

public abstract class Pet {
 // Existing attributes, constructor, getters, eat() method remain the same

 // Abstract method: no body, all concrete subclasses must implement it
 public abstract void makeSound();
}

Now new Pet("Generic", 1) will throw a compile error, but new Dog(...) and new Cat(...) are still valid, because they override the abstract makeSound() method. Abstract classes are used when you want to enforce a consistent interface for all subclasses, while still reusing shared code.

7. Common Pitfalls (and how to avoid them)

  • Wrong move: Omitting a super() call in a subclass constructor when the superclass has no no-argument constructor, leading to a compile error. Why students do it: They forget Java only inserts an implicit no-arg super() call if the superclass has a no-arg constructor. Correct move: Always explicitly call the appropriate parameterized super() constructor as the first line of your subclass constructor if the superclass has no no-arg option.
  • Wrong move: Accidentally overloading a method instead of overriding it (e.g. adding an extra parameter to the subclass method), leading to the superclass method being called unexpectedly. Why students do it: They misremember that the method signature must be exactly identical for an override. Correct move: Always use the @Override annotation when you intend to override a method; the compiler will catch signature mismatches for you.
  • Wrong move: Trying to access private superclass attributes directly from a subclass, leading to a compile error. Why students do it: They assume all superclass members are inherited and accessible. Correct move: Use public or protected getter/setter methods from the superclass to access private attributes, or change the attribute modifier to protected if appropriate.
  • Wrong move: Trying to call a subclass-only method on a superclass reference without casting, leading to a compile error. Why students do it: They confuse the reference type (which determines what methods you can call) with the actual object type (which determines what method implementation runs). Correct move: Check the object type with instanceof first, then cast to the subclass type before calling subclass-specific methods.
  • Wrong move: Trying to instantiate an abstract class directly, leading to a compile error. Why students do it: They confuse abstract and concrete classes. Correct move: Only instantiate concrete subclasses that implement all abstract methods of the abstract superclass.

8. Practice Questions (AP Computer Science A Style)

Question 1 (Multiple Choice)

Given the following code snippets:

public class Vehicle {
 private int year;
 public Vehicle(int y) { year = y; }
 public void honk() { System.out.println("Beep!"); }
}

public class Car extends Vehicle {
 private String model;
 public Car(int y, String m) {
 // Line X
 model = m;
 }
 @Override
 public void honk() { System.out.println("Car horn: Honk!"); }
 public String getModel() { return model; }
}

Which of the following can replace Line X to make the code compile? A) year = y; B) super(y); C) Vehicle(y); D) super();

Solution

Correct answer: B.

  • A is incorrect: year is private in Vehicle, so it cannot be accessed directly from the Car subclass.
  • C is incorrect: This is not valid syntax for calling a superclass constructor.
  • D is incorrect: Vehicle has no no-argument constructor, so the implicit super() call is invalid.
  • B is correct: It explicitly calls the parameterized Vehicle constructor with the y parameter, initializing the superclass attributes correctly.

Question 2 (Short Answer)

Consider the following code:

public class Food {
 public void cook() { System.out.println("Cooking food"); }
}

public class Pizza extends Food {
 @Override
 public void cook() { System.out.println("Baking pizza at 425F"); }
 public void addTopping(String topping) { System.out.println("Adding " + topping); }
}

What is the output of the following code snippet? If any line causes an error, explain why.

Food myDinner = new Pizza();
myDinner.cook();
myDinner.addTopping("Pepperoni");

Solution

  • Line 1 compiles successfully: Pizza IS-A Food, so a superclass Food reference can point to a Pizza object.
  • Line 2 outputs Baking pizza at 425F: Runtime polymorphism uses the actual object type (Pizza) to call the overridden cook() method.
  • Line 3 throws a compile error: The reference type Food has no addTopping() method, even though the actual object is a Pizza. To fix this line, cast the reference to Pizza: ((Pizza) myDinner).addTopping("Pepperoni"); which will run successfully.

Question 3 (Free Response Snippet)

An abstract class Shape is defined with an abstract method getArea() that returns a double. Write a concrete subclass Rectangle that extends Shape, has private width and height attributes, a constructor that takes width and height as double parameters, and overrides getArea() to return the area of the rectangle, calculated as .

Solution

public class Rectangle extends Shape {
 private double width;
 private double height;

 public Rectangle(double w, double h) {
 width = w;
 height = h;
 }

 @Override
 public double getArea() {
 return width * height;
 }
}

Explanation: The Rectangle class extends the abstract Shape class, adds the required attributes, initializes them in the constructor, and overrides the abstract getArea() method. This makes Rectangle a concrete class that can be instantiated.

9. Quick Reference Cheatsheet

Concept Core Rule
Superclass/Subclass Subclasses inherit all public/protected superclass members; private superclass members are not directly accessible
extends keyword Java supports single inheritance: a class can extend only one superclass
super call Must be the first line of a subclass constructor; required if the superclass has no no-argument constructor
Method Overriding Requires exact matching method signature, compatible return type, and access modifier no more restrictive than the superclass
@Override annotation Optional but recommended; catches signature mismatch errors at compile time
Polymorphism IS-A Superclass references can point to any subclass object; the method implementation called is determined by the actual object type at runtime
Abstract Class Cannot be instantiated; concrete subclasses must override all abstract methods defined in the abstract superclass

10. What's Next

Inheritance is the foundation for all advanced OOP concepts in the AP CS A syllabus, including interfaces, the universal Object superclass, and the hierarchical structure of the Java standard library. You will use inheritance extensively in free-response questions, which make up 50% of your total exam score, particularly in questions that ask you to extend existing provided classes to add custom functionality. Mastering inheritance is also critical for understanding recursion and sorting algorithms, which build on OOP principles tested in this unit.

If you have questions about any of the concepts in this guide, or want to practice more inheritance problems tailored to your weak spots, you can ask Ollie, our AI tutor, at any time. Head to the homepage to access full timed practice exams, personalized study plans, and more AP CS A resources to help you score a 5 on exam day.

← Back to topic

Stuck on a specific question?
Snap a photo or paste your problem — Ollie (our AI tutor) walks through it step-by-step with diagrams.
Try Ollie free →