/**
 * Any class that has an adjustable volume may implement this interface.
 */
public interface Audible
{
    int MAX_VOLUME = 10;

    int getVolume();

    void setVolume(int volume);
}


/**
 * Any class is rechargable may implement this interface.
 */
public interface Rechargeable
{
    public void recharge();
}


/**
 *  Cell Phones are not toys. 
 */
public class CellPhone implements Rechargeable, Audible
{
    private int chargeLevel;
    private int volume;
    
    
    public CellPhone(int chargeLevel, int volume)
    {
        this.chargeLevel = chargeLevel;
        this.volume = volume;
    }

    public int getVolume()
    { 
        return volume;
    }
    
    public void setVolume(int volume)
    {
        this.volume = volume;
    }

    public void makeCall()
    {
        System.out.println("Riing... Hello.");
    }
    
    public void recharge()
    {
        chargeLevel = 10;
        System.out.println("All charged up!");
    }

}



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

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

    public abstract void makeNoise();

    public int getVolume()
    {
        return volume;
    }

    public void setVolume(int volume)
    {
        this.volume = volume;
    }

}

/**
 * A rechargable toy robot.
 */
public class ToyRobot extends LoudToy implements Rechargeable
{
    private int chargeLevel;

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

    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
{

    public ToySheep()
    {
        super(3);
    }

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

}


public class RechargeDriver
{

    public static void main(String[] args)
    {
        ArrayList<Rechargeable> items = new ArrayList<>();
        items.add(new ToyRobot());
        items.add(new CellPhone(4, 5));

        // The power of polymorphism through interfaces! The same method can
        // operate on ToyRobots and CellPhones even though they are not related
        // through inheritance.
        
        rechargeAll(items);

    }

    public static void rechargeAll(ArrayList<Rechargeable> items)
    {
        for (Rechargeable item : items)
        {
            item.recharge();
        }
    }
}