CS 199 EMP

Hosted by Jackie Chan and Akhila Ashokan

Topics: Inheritance Cont., Polymorphism, and Upcasting/Downcasting Mechanics

Today's Learning Objectives

  • Inheritance Cont.

  • Polymorphism

  • Upcasting, Downcasting

  • instanceof

  • @Override

Write code on the homepage or any playground on the site!

Slides are on the course site!

Brief Review of Inheritance

Inheritance is the ability for an object to inherit behaviors (both methods and states) from a parent object.

class Enemy { // Enemy is the parent class.
  int health;
  int maxHealth;
  int mana;
  int maxMana;

class Witch extends Enemy { // Witch is the child class.
  int castFireball() {
    mana -= 5;
    int damage = maxHealth * 5;
    return damage;

Practice with Inheritance (5 minutes)

  1. Why is inheritance valuable?

  2. What are some situations that are ideal for inheritance?

  3. Are private fields and functions available to children?

Object: The Common Ancestor

Remember, that all objects have a common ancestor! All objects, despite it not be explicit, inherit behaviors from the Object class. The most prevalent of them is myObject.toString().

Whenever you call a function/variable within an object, Java will traverse the family tree from child all the way up to Object to find it.

On the next slide, you'll practice these ideas with the Enemy class again! About 5 minutes on the next slide.

Enemies Tree

Polymorphism, Excuse Me?

Polymorphism is the idea that objects can morph into multiple (hence the poly) different objects.

// Pet is a Object
class Pet { }

// Dog is a Pet
// Dog is a Object
class Dog extends Pet { }

// Mutt is a Dog
// Mutt is a Pet
// Mutt is a Object
class Mutt extends Dog { }

Practice with Polymorphism (5 minutes)

Given this code, answer the questions:

class FlyingObject { }
class UFO extends FlyingObject { }
class Airplane extends FlyingObject { }
class JetLiner extends Airplane { }
class AirbusA380 extends JetLiner { }
class Missile extends FlyingObject { }

// What objects are acceptable for these functions?
void foo(Object o) { }
void voo(JetLiner j) { }
void too(UFO u) { }
void woo(FlyingObject f) { }

Upcasting and Downcasting

Upcasting is easy. Java can figure it out, consider this:

FlyingObject myPrivateJet = new JetLiner();

Downcasting is annoying.

FlyingObject myPrivateJet = new JetLiner();

if (myPrivateJet instanceof JetLiner) { // Check if downcasting is possible.
  JetLiner jet = (JetLiner) myPrivateJet; // Downcasting.
  // Now I have access to JetLiner unique fields and methods.

// Does the same thing.
if (myPrivateJet instanceof JetLiner jet) {

Practice with Upcasting/instanceof/@Override

Here, we'll be comparing Enemy objects. Two enemies are equal to each other if they have the same maxHealth and maxMana. Write a equals() function in the Enemy class to compare different enemies.

Starter Code (10 minutes)

class Enemy {
  int maxHealth;
  int maxMana;

  // some annotation here
  public boolean equals(Object o) {

    // check if o is an instance of an Enemy.

    // cast and check maxHealth and maxMana.


class Dragon extends Enemy { }
class Griffin extends Enemy { }

Dragon d = new Dragon();
d.maxHealth = 100;
d.maxMana = 200;

Griffin g = new Griffin();
g.maxHealth = 100;
g.maxMana = 200;

// Should print out true.

Copying Practice: Goblin Army! (5 minutes)

Write a copy constructor that will copy a given Goblin object.

class Goblin {
  String clan;
  String weapon;
  Goblin(Goblin c) {
    // Your code here.

int armySize = 100;
Goblin original = new Goblin();
original.clan = "Highlands";
original.weapon = "Spear";

Goblin[] army = new Goblin[armySize];

for (int i = 0; i < armySize; i++) {
  army[i] = new Goblin(original);

Holy Moly We Covered A Lot! Let's Summarize.

We covered these ideas:

  1. What is inheritance, and why it's important.

  2. What is polymorphism, what does it allow us to do?

  3. How to do upcasting and downcasting, instanceof, and @Override.

  4. How to copy objects using constructors.

Any questions about any of this?

Great! You made it to the end of the week.

Have a good weekend. Give us some feedback if you like, and we hope you have an amazing weekend.

Solutions Section

Inheritance Answers

  1. Inheritance allows us to reuse code by inheriting behaviors from parent objects. Reducing the amount of code causes fewer errors and allows us to change behavior for a family of children objects.

  2. Think about Car objects and particular types of cars, e.g. Racecar, Truck, etc. Other situations may be Building and Skyscraper, Library, and House as the children.

  3. private fields and functions are not available for children. protected, public, and default are all available to children.

Enemies Answers

  1. Necromancer will look for a health variable in its own class, Necromancer, and not find it. It'll go up, check the Enemy class and find the health variable.

  2. Hydra will look for the stab() function within itself, then in Dragon, Enemy, and finally Object` and not find it. It will result in an error.

Polymorphism Answers

// Runs with everything. All objects are Objects.
void foo(Object o) { }

// Runs with JetLiners and AirbusA380 because AirbusA380
// *is a* JetLiner too.
void voo(JetLiner j) { }

// Only runs with UFO objects.
void too(UFO u) { }

// Runs with all children because objects like Missiles *are*
// FlyingObjects too through polymorphism.
void woo(FlyingObject f) { }

Upcasting/instanceof/@Override Solution

class Enemy {
  int maxHealth;
  int maxMana;

  public boolean equals(Object o) {

    if (o instanceof Enemy) {
      Enemy e = (Enemy) o;
      if (e.maxHealth == this.maxHealth && e.maxMana == this.maxMana) {
        return true;    
    return false;


Goblin Army Solution

class Goblin {

  String clan;
  String weapon;

  Goblin(Goblin c) {
    this.clan = c.clan;
    this.weapon = c.weapon;