Polymorphism

Nathan Sprague

LoudToy

/**
 * Class representing a generic loud toy. 
 * Exists only to serve as a superclass.
 */
public class LoudToy
{
    public void makeNoise()
    {
        // This should be overridden in subclasses.
        System.out.println("Generic noise.");
    }
}

ToyRobot

public class ToyRobot extends LoudToy
{
    private int chargeLevel;
    
    public ToyRobot()
    {
        chargeLevel = 5;
    }

    @Override
    public void makeNoise()
    {
        System.out.println("Beep Beep!");
    }

    public void recharge()
    {
        chargeLevel = 10;
        System.out.println("Charged up!");
    }
}

Quiz...

What will be printed?

ToyRobot robot; 
robot = new ToyRobot();
robot.makeNoise();
robot.recharge();

ToySheep

/**
 * Class representing a generic loud toy. 
 * Exists only to serve as a superclass.
 */
public class LoudToy
{
    public void makeNoise()
    {
        // This should be overridden in subclasses.
        System.out.println("Generic noise.");
    }

}
public class ToyRobot extends LoudToy
{
    private int chargeLevel;

    public ToyRobot()
    {
        chargeLevel = 5;
    }

    @Override
    public void makeNoise()
    {
        System.out.println("Beep Beep!");
    }

    public void recharge()
    {
        chargeLevel = 10;
        System.out.println("Charged up!");
    }
}
/**
 * A toy sheep that says "Baaa."
 */
public class ToySheep extends LoudToy
{
    @Override
    public void makeNoise()
    {
        System.out.println("Baaa.");
    }
}

Socrative Quiz...

What will be printed?

LoudToy toy;
toy = new ToySheep();
toy.makeNoise();
toy = new ToyRobot();
toy.makeNoise();
  1. Generic noise.
    Generic noise.
  2. Baaa.
    Beep Beep!
  3. Generic noise.
    Baaa.
    Generic noise.
    Beep Beep!
  4. Will not compile

Socrative Quiz...

Which code sample will result in the following terminal output?

Beep Beep!
Charged up!
  1. LoudToy toy;
    toy = new ToyRobot();
    toy.makeNoise();
    toy.recharge();
  2. LoudToy toy;
    ToyRobot bot;
    toy = new ToyRobot();
    toy.makeNoise();
    bot = toy;
    bot.recharge();
  3. LoudToy toy;
    ToyRobot bot;
    toy = new ToyRobot();
    toy.makeNoise();
    bot = (ToyRobot)toy;
    bot.recharge();
  4. None of the above.

  5. More than one of the above.

How about this...

LoudToy toy;
ToyRobot bot;
toy = new ToySheep();
bot = (ToyRobot)toy;
bot.makeNoise();

Will it compile? Will it execute without an exception? If so, what will be printed?

Adding Volume...

One option...

/**
 * Class representing a generic loud toy. 
 * Exists only to serve as a superclass.
 */
public class LoudToy
{
    private int volume;

    public LoudToy(int volume)
    {
        this.volume = volume;
    }

    public void makeNoise()
    {
        // This should be overridden in subclasses.
        System.out.println("Generic noise.");
    }

    public int getVolume()
    {
        return volume;
    }

    public int setVolume(int volume)
    {
        this.volume = volume;
    }
}
public class ToyRobot extends LoudToy
{
    private int chargeLevel;

    public ToyRobot()
    {
        super(10);
        chargeLevel = 5;
    }

    @Override
    public void makeNoise()
    {
        if (getVolume() > 5)
    {
           System.out.println("BEEP BEEP!");
    }
    }

    public void recharge()
    {
        chargeLevel = 10;
        System.out.println("Charged up!");
    }
}
/**
 * A toy sheep that says "Baaa."
 */
public class ToySheep extends LoudToy
{
    public ToySheep()
    {
        super(3);
    }

    @Override
    public void makeNoise()
    {
        System.out.println("Baaa.");
    }
}

Protected Access...

Protected members are visible in all subclasses (and all other classes in the same package).

/**
 * Class representing a generic loud toy. 
 * Exists only to serve as a superclass.
 */
public class LoudToy
{
    protected int volume;

    public LoudToy(int volume)
    {
        this.volume = volume;
    }

    public void makeNoise()
    {
        // This should be overridden in subclasses.
        System.out.println("Generic noise.");
    }

    public int getVolume()
    {
        return volume;
    }

    public int setVolume(int volume)
    {
        this.volume = volume;
    }
}
public class ToyRobot extends LoudToy
{
    private int chargeLevel;

    public ToyRobot()
    {
        super(10);
        chargeLevel = 5;
    }

    @Override
    public void makeNoise()
    {
        if (volume > 5)
    {
           System.out.println("BEEP BEEP!");
    }
    }

    public void recharge()
    {
        chargeLevel = 10;
        System.out.println("Charged up!");
    }
}
/**
 * A toy sheep that says "Baaa."
 */
public class ToySheep extends LoudToy
{
    public ToySheep()
    {
        super(3);
    }

    @Override
    public void makeNoise()
    {
        System.out.println("Baaa.");
    }
}

Overloaded Methods...

/**
 *  Utility methods to help us play with toys.
 */
public class PlayUtils
{
    public static void playWithLoudToy(LoudToy toy)
    {
        System.out.println("This is a fun loud toy!");
        toy.makeNoise();
    }

    public static void playWithLoudToy(ToyRobot robot)
    {
        System.out.println("This is a fun robot!");
        robot.makeNoise();
    }
}
ToyRobot bot = new ToyRobot();
LoudToy toy = bot;
ToySheep sheep = new ToySheep();

PlayUtils.playWithLoudToy(bot);
PlayUtils.playWithLoudToy(toy);
PlayUtils.playWithLoudToy(sheep);