← Skill tree CS Skill Tree 0 CSCD211

IS-A Is Inheritance

Textbook: BJP (Reges and Stepp)

Before You Start

Check each box you can do from memory. A box you cannot check yet is not a problem; it points you to a quick refresher, not a grade.

Not sure? Take the 60-second self-check.

1. extends. class Dog extends Animal means what?

Check

Dog is a subclass of Animal. Every Dog object can be used wherever an Animal is expected. Dog inherits Animal’s non-private fields and methods and may override them.

2. implements. class Circle implements Drawable means what?

Check

Circle provides a concrete implementation of every abstract method declared in Drawable. Circle IS-A Drawable; any code that takes a Drawable argument will accept a Circle.

3. HAS-A marker. What syntactic element in a class declaration establishes a HAS-A relationship?

Check

A field declaration of the other class’s type. For example, private Engine engine; in a Car class says Car HAS-A Engine.


Try This First

Classify each relationship as IS-A or HAS-A:

// (a)
class Engine { ... }
class Car { private Engine engine; ... }

// (b)
class Dog extends Animal { ... }

// (c)
class TeamComparator implements Comparator<Player> { ... }
Check

(a) HAS-A: Car has a field of type Engine.

(b) IS-A: extends is the IS-A keyword for classes.

(c) IS-A: implements is the IS-A keyword for interfaces. TeamComparator IS-A Comparator<Player>.


What You Need To Walk In With

The Insight: IS-A in Java is marked by a keyword: extends (class inheritance) or implements (interface implementation). HAS-A is marked by a field declaration. These are structural relationships written in the source code, not interpretations. The keyword rule is unambiguous: find extends or implements in the class declaration, and you have IS-A. Find a field of another class type, and you have HAS-A.

Notice that extends and implements serve the same IS-A purpose but for different kinds of types: extends names exactly one parent class, while implements can name one or more interfaces, and both appear in the class declaration header as explicit, keyword-marked declarations. The third relationship worth keeping distinct is pure usage: when a class mentions another type only inside a method body (as a parameter type or local variable), that is association, sometimes called “uses-A.” It does not appear in the class header at all, and it does not change what the class IS.

You can: identify the IS-A relationships in any class declaration by scanning for extends/implements; identify HAS-A by scanning fields; recognize that a compareTo method is the fulfillment of an IS-A contract, not evidence of a new field-based relationship; and apply both rules to the F19 Lab 1 classes without hesitation.


How It Works

The keyword rule

Relationship Established by Example
IS-A (class inheritance) extends in class declaration class Dog extends Animal
IS-A (interface) implements in class declaration class Circle implements Drawable
HAS-A Field of another class type private Engine engine; in Car

Both extends and implements establish IS-A because both grant substitutability: wherever the parent type or interface is expected, the child or implementing class is accepted.

What IS-A provides: substitutability

The key consequence of IS-A is that code written for the parent type accepts objects of the subtype without modification. This is the Liskov substitution principle: if S IS-A T, then a T variable can hold an S reference, and any operation valid on T is valid on the actual S object at runtime.

Animal a = new Dog();     // Dog IS-A Animal: valid
Comparator<Player> c = new TeamComparator();   // IS-A Comparator<Player>: valid

HAS-A does not provide this. A Car is not substitutable for an Engine just because it contains one.

F19 Lab 1: IS-A and HAS-A side by side

From F19 Lab 1:

IS-A relationships:
  Player implements Comparable<Player>
  TeamComparator implements Comparator<Player>
  PositionComparator implements Comparator<Player>
  GamesPlayedComparator implements Comparator<Player>

HAS-A relationships:
  Player HAS-A team (String)
  Player HAS-A position (Position enum)
  Player HAS-A gamesPlayed (int)
  Team HAS-A name (String)

The lab uses IS-A exclusively for interface implementation, not for class-to-class extension. This is intentional: composition is the primary structural tool; inheritance is used only to satisfy interface contracts.


Worked Example: Predict Then Check

Label each line as IS-A or HAS-A:

public class Player implements Comparable<Player>
{
    private String lastName;        // (a)
    private Position position;      // (b)
    private Team team;              // (c)

    @Override
    public int compareTo(final Player other) { ... }  // (d): what relationship does this implement?
}
Reasoning

(a) HAS-A: field of type String.

(b) HAS-A: field of type Position (an enum).

(c) HAS-A: field of type Team.

(d) This provides the implementation for the IS-A relationship Player implements Comparable<Player>. The method itself is not a field, so it is not HAS-A; it is part of satisfying the IS-A contract.

Show answer

(a) HAS-A (b) HAS-A (c) HAS-A (d) IS-A implementation (the method is the concrete realization of Player IS-A Comparable<Player>)

Quick check

Check your understanding

In the Player class shown above, what establishes the IS-A relationship with Comparable<Player>?

Tier 2 · BJP (Reges and Stepp), Ch 10


Common Misconceptions

Misconception 1: treating implements Comparable<T> as HAS-A

Wrong mental model: “Player HAS-A compareTo method, so the relationship with Comparable<Player> is HAS-A.”

Why it breaks: HAS-A describes fields, not methods. implements Comparable<Player> is the IS-A declaration: Player IS-A Comparable<Player>. The fact that Player supplies a compareTo method is how the IS-A contract is fulfilled, not evidence of HAS-A.

How to correct: Look at the class header. implements Comparable<Player> is there. The keyword implements marks IS-A, regardless of what the implementation consists of.

Source: JLS §8.1.5.

Quick check

Check your understanding

A classmate says: ‘Player HAS-A compareTo, so Player HAS-A Comparable<Player>.’ Which response best corrects the error?

Tier 2 · BJP (Reges and Stepp), Ch 10


Misconception 2: treating a method parameter or local variable type as establishing IS-A

Wrong mental model:Arrays.sort(nflPlayers, new TeamComparator()) means the main class IS-A Comparator because it uses one.”

Why it breaks: Using a type as a method argument or return type is an association: a “uses” relationship, not IS-A and not HAS-A. IS-A requires extends or implements in the class declaration. Association is transient; it does not change what the class IS.

How to correct: Restrict IS-A claims to class declarations. Look for extends/implements in the class header, not in method bodies.


Formal Definition and Interface Contract

From JLS §8.1.4 (Superclasses):

The extends clause specifies the superclass of a class. [...] The subclass inherits from the superclass all public and protected members.

From JLS §8.1.5 (Superinterfaces):

The implements clause specifies all the interfaces implemented by a class. [...] A class implements all the interfaces named in its implements clause.

Liskov substitution principle: if S is a subtype of T, then objects of type T in a program may be replaced with objects of type S without altering any of the desirable properties of that program.


Mental Model

Think of IS-A as a membership card: class Dog extends Animal gives every Dog object an Animal membership card. Any club that admits Animal members admits Dog members without checking further. implements works the same way for interfaces. HAS-A is different: it says a Car carries an Engine in its trunk, but that does not make a Car usable as an Engine.


Connections

Within CSCD 210/211: Every implements in the comparator material established an IS-A relationship. This leaf makes that relationship explicit and names it. The full mechanics of extends are covered later; this covers only the structural label.

Looking back: CSCD 210 introduced extends and implements. This leaf applies those keywords to the IS-A classification.

Looking ahead: Favor Composition over Inheritance explains when IS-A is the wrong design choice and HAS-A should be used instead. Association: Uses-A and Aggregation: Has-A, Can Outlive go deeper into the spectrum between the two.


Go Deeper (optional)

None of what follows is needed to write correct IS-A and HAS-A classifications. It is here for the reader who wants to see where these ideas connect to larger patterns in software design and theory.

Professional codebases. IS-A and HAS-A are the two most fundamental object-design relationships. The ability to distinguish them on sight is a prerequisite for any design discussion, code review, or inheritance decision in a professional Java codebase. When a senior engineer says “prefer composition over inheritance,” they mean: reach for HAS-A by default and use IS-A only when substitutability is the explicit goal.

Effective Java, Item 18. Joshua Bloch’s argument (in Effective Java, third edition) is that IS-A through extends should be used only when the subclass genuinely passes every test the superclass promises to pass. When in doubt, encapsulate the other class as a field (HAS-A) rather than extending it. The next concept in this tree develops exactly that argument.

The Comparator as a function object and a design pattern. A TeamComparator implements Comparator<Player> is not only an IS-A relationship: it is also a first instance of the Strategy pattern from Gamma et al. (Design Patterns, 1994), where an algorithm is encapsulated in its own object so it can be swapped at runtime. That pattern is the simplest form of a first-class function in a language that did not originally have lambdas; Java 8 lambdas and method references are the modern shorthand for the same idea.

Type theory. The Liskov substitution principle is formalized in type theory as the subtype relation, written S <: T. What Java’s type system enforces is syntactic subtyping: if S extends T, the compiler permits S wherever T is expected. Full behavioral subtyping (the original Liskov and Wing 1994 criterion) adds the requirement that preconditions cannot be strengthened and postconditions cannot be weakened in the subtype, which Java does not verify at compile time. That gap is why the principle is stated as a design rule rather than a compiler guarantee.


Practice

Level 1

Classify each relationship as IS-A or HAS-A and name the keyword or element that establishes it:

(a) class Sandwich implements Comparable<Sandwich> { ... }
(b) class Sandwich { private String name; ... }
(c) class GuestEmployee extends Employee { ... }
(d) class Team { private Player[] roster; ... }
Show answer

(a) IS-A; keyword: implements (b) HAS-A; element: field private String name (c) IS-A; keyword: extends (d) HAS-A; element: field private Player[] roster


Level 2

In F19 Lab 1, GamesPlayedComparator sorts Player objects. Identify: (a) the IS-A relationship this class declares, (b) the HAS-A relationships Player has, and (c) whether GamesPlayedComparator HAS-A Player.

Show answer

(a) GamesPlayedComparator implements Comparator<Player> (IS-A Comparator<Player>).

(b) Player HAS-A lastName (String), position (Position enum), team (String or Team), gamesPlayed (int).

(c) No. GamesPlayedComparator has no Player field. It uses Player objects in method parameters, which is association (a “uses” relationship), not HAS-A.

Source: F19.Lab1-Review.


Level 3

A student says: “Employee HAS-A compareTo method, so it IS-A employee ordering.” Refute this in two sentences, using the keyword rule.

Show answer

Supplying a compareTo method is the implementation of a declared IS-A relationship, not a HAS-A relationship. The correct classification requires looking at the class header: if it says implements Comparable<Employee>, then Employee IS-A Comparable<Employee>; the method is the fulfillment of that contract, not a field.


Check Yourself

Close the notes and answer each one from memory, then reveal it. Pulling an idea back from memory is one of the strongest ways to make it stick.

Check your understanding

Which two keywords in a Java class declaration establish an IS-A relationship?

Tier 1 · BJP (Reges and Stepp), Ch 10

A class declares: class TeamComparator implements Comparator<Player>. What relationship does this establish between TeamComparator and Comparator<Player>?

Tier 1 · BJP (Reges and Stepp), Ch 10

Which of the following class declarations creates a HAS-A relationship?

Tier 1 · BJP (Reges and Stepp), Ch 10

Given the code below, which assignment compiles without error? Animal a; Dog d = new Dog(); Comparator<Player> c; (i) a = d; (ii) d = a; (iii) c = new TeamComparator(); (iv) a = new TeamComparator();

Tier 2 · BJP (Reges and Stepp), Ch 10

A student says: ‘Player HAS-A compareTo method, so the relationship between Player and Comparable<Player> is HAS-A.’ What is wrong with this reasoning?

Tier 3 · BJP (Reges and Stepp), Ch 10