AP Computer Science A Inheritance — Worked Answer Explanations
Unit 9 · 12 questions explained
Below is a complete answer key for our AP Computer Science A Inheritance practice questions. For each question you'll find the correct choice, a full written explanation of how to get there, and — for every wrong answer — a short note on exactly why it's tempting and where it goes wrong. Reading these straight through is one of the fastest ways to find the gaps in a unit before exam day.
Prefer to test yourself first? Take the timed Inheritance practice test and come back here to review, or head back to the Inheritance unit overview.
- Question 1 · Easy
Given the following classes:
public class Animal { public String speak() { return "..."; } } public class Dog extends Animal { public String speak() { return "Woof"; } }What does the following print?
Animal a = new Dog(); System.out.println(a.speak());- A
...Why not A: Used the declared type (Animal) to determine which method runs, ignoring runtime polymorphism. - B
WoofCorrect - CCompile error: cannot assign Dog to Animal variableWhy not C: A subclass object can always be assigned to a superclass variable (upcasting is automatic).
- D
...WoofWhy not D: Assumed both the superclass and subclass versions of speak() are called and concatenated.
ExplanationJava uses dynamic dispatch: the method called is determined by the actual runtime type of the object, not the declared type. The object is a Dog at runtime, so Dog's
speak()returns "Woof".Key takeawayPolymorphism: the runtime type determines which overriding method executes, not the declared reference type.
- A
- Question 2 · Easy
Which keyword is used to indicate that one class inherits from another in Java?
- A
implementsWhy not A: implements is used for interfaces, not class-to-class inheritance. - B
inheritsWhy not B: inherits is not a Java keyword; it exists in some other languages. - C
extendsCorrect - D
superWhy not D: super is used inside a class to call a parent's constructor or method, not to declare inheritance.
ExplanationIn Java,
class Child extends Parentdeclares that Child inherits fields and methods from Parent.implementsis for interfaces;superis for accessing parent members;inheritsdoes not exist in Java.Key takeawayUse extends to declare class inheritance; use implements to adopt an interface.
- A
- Question 3 · Easy
What is the output of the following code?
public class Shape { public String describe() { return "Shape"; } } public class Circle extends Shape { public String describe() { return super.describe() + "-Circle"; } } // In main: Circle c = new Circle(); System.out.println(c.describe());- A
ShapeWhy not A: Only printed the superclass result, ignoring Circle's additional "-Circle" concatenation. - B
CircleWhy not B: Only printed the subclass part, omitting the super.describe() prefix. - C
Shape-CircleCorrect - DCompile error: super.describe() is not allowedWhy not D: super.describe() is valid and commonly used to extend superclass behavior.
ExplanationCircle.describe()callssuper.describe()which returns "Shape", then concatenates "-Circle" to produce "Shape-Circle". Usingsuperallows a subclass to build on the superclass implementation.Key takeawaysuper.method() calls the parent class's version, allowing a subclass to extend rather than completely replace the parent's behavior.
- A
- Question 4 · Easy
Consider the following class hierarchy:
public class Vehicle { private String brand; public Vehicle(String brand) { this.brand = brand; } public String getBrand() { return brand; } } public class Car extends Vehicle { private int doors; public Car(String brand, int doors) { super(brand); this.doors = doors; } }Which statement about Car's constructor is true?
- AIt will cause a compile error because Car does not declare the
brandfield.Why not A: Car passes brand to Vehicle via super(); it does not need to redeclare the field. - BThe
super(brand)call must be the last statement in the constructor.Why not B: super() must be the FIRST statement in a constructor, not the last. - CIt correctly delegates brand initialization to the Vehicle constructor via super().Correct
- DWithout a no-arg constructor in Vehicle, this code will not compile.Why not D: Car explicitly calls super(brand), which matches Vehicle's one-arg constructor; a no-arg constructor is not required.
Explanationsuper(brand)must appear as the first statement in the child constructor and invokes the parent's matching constructor. This correctly initializes thebrandfield that Vehicle owns. No no-arg constructor is needed because Car supplies the required argument.Key takeawaysuper(...) must be the first statement in a subclass constructor and delegates initialization to the matching parent constructor.
- A
- Question 5 · Easy
Which of the following best describes the difference between method overriding and method overloading?
- AOverriding changes the return type; overloading changes the method name.Why not A: Overriding replaces a parent method with the same signature; overloading adds a same-named method with a different parameter list.
- BOverriding occurs within the same class; overloading occurs across parent and child classes.Why not B: The definitions are reversed: overloading can occur in one class; overriding spans a parent-child relationship.
- COverriding redefines a parent's method with the same signature in a subclass; overloading defines multiple methods with the same name but different parameter lists.Correct
- DOverriding and overloading are the same concept but use different keywords.Why not D: They are distinct concepts; overriding requires the same signature, while overloading requires different parameter lists.
ExplanationOverriding: a subclass provides a new implementation of an inherited method with the identical signature (name + parameter types). Overloading: the same class (or a related one) defines multiple methods with the same name but different parameter lists.
Key takeawayOverride = same signature, different class in hierarchy. Overload = same name, different parameter list.
- A
- Question 6 · Easy
Given the following code:
Animal a = new Dog(); if (a instanceof Dog) { System.out.println("Dog"); } else { System.out.println("Not Dog"); }What is printed, assuming
Dog extends Animal?- A
Not DogWhy not A: Checked the declared type (Animal) rather than the runtime object type (Dog). - BCompile error: cannot use instanceof with a parent type variableWhy not B: instanceof works on any reference type; it is not restricted by the declared type of the variable.
- C
DogCorrect - DRuntime exception: ClassCastExceptionWhy not D: instanceof does not cast; it is a safe test and never throws a ClassCastException.
Explanationinstanceofchecks the actual runtime type of the object. The object was created asnew Dog(), soa instanceof Dogis true and "Dog" is printed. No cast occurs and no exception is thrown.Key takeawayinstanceof checks the runtime type of an object, not the declared type of the variable holding it.
- A
- Question 7 · Medium
What is the result of the following code?
public class A { public int value() { return 1; } } public class B extends A { public int value() { return 2; } } public class C extends B { // no override } // In main: A obj = new C(); System.out.println(obj.value());- A1Why not A: Used A's version because the declared type is A, ignoring runtime polymorphism.
- B2Correct
- CCompile error: C does not define value()Why not C: C inherits value() from B; no compile error occurs.
- D3Why not D: Assumed a sum or further modification of value() happens automatically through the chain.
ExplanationC inherits value() from B (which returns 2) because C does not override it. Dynamic dispatch uses C's most specific implementation, which is B's overriding version. A's version is never reached. Output: 2.
Key takeawayA subclass inherits the most specific overriding method from its nearest ancestor that provides one.
- A
- Question 8 · Medium
A class declares
public String toString(). Which statement is true about this method?- AIt overloads the Object class's toString() because all classes implicitly extend Object.Why not A: It overRIDES (not overloads) toString(); the signature is identical to Object.toString().
- BIt overrides Object's toString() and is called automatically by print methods and string concatenation.Correct
- CIt must call super.toString() or a compile error occurs.Why not C: Calling super.toString() is optional; a complete custom implementation is valid on its own.
- DIt has no effect because Java does not use toString() automatically.Why not D: Java's println and string concatenation (+) automatically call toString() on objects.
ExplanationEvery Java class implicitly extends Object. Declaring
public String toString()with that exact signature overrides Object's version. Java's I/O methods (System.out.println, string concatenation) call toString() automatically on objects.Key takeawayOverriding toString() enables custom string representations used automatically by println and the + operator.
- A
- Question 9 · Medium
An abstract class
Figureis defined as:public abstract class Figure { public abstract double area(); public void printArea() { System.out.println("Area: " + area()); } }Which of the following statements is true?
- A
new Figure()is valid because Figure has a concrete method.Why not A: Abstract classes cannot be instantiated regardless of whether they contain concrete methods. - BAny concrete subclass of Figure must provide an implementation of area().Correct
- CAbstract classes cannot have concrete methods like printArea().Why not C: Abstract classes may contain any mix of abstract and concrete methods.
- DprintArea() will not compile because area() has no implementation in Figure.Why not D: Concrete methods in an abstract class may call abstract methods; the call resolves at runtime through dynamic dispatch.
ExplanationAbstract classes cannot be instantiated directly. Any non-abstract subclass must implement all abstract methods (here,
area()). Abstract classes may freely contain concrete methods;printArea()callsarea()which resolves polymorphically at runtime.Key takeawayConcrete subclasses of an abstract class must implement all abstract methods; abstract classes themselves cannot be instantiated.
- A
- Question 10 · Hard
Which of the following correctly demonstrates the use of
equals()from the Object class, and when would you override it?public class Point { int x, y; public Point(int x, int y) { this.x = x; this.y = y; } } Point p1 = new Point(2, 3); Point p2 = new Point(2, 3); System.out.println(p1.equals(p2));- APrints
truebecause p1 and p2 have the same x and y values.Why not A: Object's default equals() compares references, not field values; p1 and p2 are different objects. - BPrints
false; to gettrue, Point must override equals() to compare x and y.Correct - CCauses a compile error because equals() cannot be called on user-defined classes.Why not C: All Java classes inherit equals() from Object; it can always be called.
- DPrints
trueonly if the two objects were created in the same statement.Why not D: Reference equality depends on object identity, not how or when the object was created.
ExplanationObject's default
equals()checks reference equality (same object in memory). Since p1 and p2 are distinct objects,p1.equals(p2)returns false. To compare by field values, Point must override equals() with a custom implementation comparing x and y.Key takeawayObject.equals() tests reference equality by default; override it to compare objects by meaningful field values.
- A
- Question 11 · Hard
Consider the following hierarchy:
public class Vehicle { public void move() { System.out.println("Vehicle moves"); } } public class Boat extends Vehicle { public void move() { System.out.println("Boat sails"); } } public class AmphibiousVehicle extends Boat { }What is printed by:
Vehicle v = new AmphibiousVehicle(); v.move();- A
Vehicle movesWhy not A: Vehicle.move() is the declared type's version; dynamic dispatch resolves to the runtime type's nearest override. - B
Boat sailsCorrect - C
Vehicle movesBoat sailsWhy not C: Both versions are not called; only the most specific overriding method is executed. - DCompile error: AmphibiousVehicle does not define move()Why not D: AmphibiousVehicle inherits move() from Boat; no compile error occurs.
ExplanationAmphibiousVehicle does not override move(), so it inherits Boat's version. Dynamic dispatch for
new AmphibiousVehicle()finds the nearest override, which is Boat.move(). Output: "Boat sails".Key takeawayInherited methods resolve to the nearest ancestor's override; the runtime type's method lookup walks up the hierarchy until it finds an implementation.
- A
- Question 12 · Hard
A programmer writes:
public class Printer { public void print(String s) { System.out.println(s); } public void print(int n) { System.out.println(n * 2); } } Printer p = new Printer(); p.print(5);What is the output, and what concept does this demonstrate?
- APrints
5; demonstrates method overriding.Why not A: Method overriding involves a subclass redefining a parent's method with the same signature; these are two methods in the same class with different parameter types. - BCompile error: two methods cannot have the same name.Why not B: Java allows multiple methods with the same name as long as they have different parameter lists (overloading).
- CPrints
10; demonstrates method overloading.Correct - DPrints
5; demonstrates polymorphism through inheritance.Why not D: Overloading is resolved at compile time by the argument type; p.print(5) matches print(int) and prints n*2 = 10, not 5.
ExplanationTwo methods named
printin the same class with different parameter types (Stringvsint) is method overloading.p.print(5)resolves toprint(int)at compile time, executing5 * 2 = 10. Output:10.Key takeawayOverloading is compile-time resolution by parameter type; calling print(5) dispatches to print(int), not print(String).
- A