package interfaces;

/**
 * The Car class implements the MakesSound interface but not the Swims
 * interface.
 
 @author Grant Braught
 @author Dickinson College
 @version Aug 20, 2009
 */
public class Car implements MakesSound {

    private String make;
    private int volume;
    
    public Car(String make, int volume) {
        this.make = make;
        this.volume = volume;
    }

    public String getMake() {
        return make;
    }

    // === Implementation of the MakesSound interface ===

    public void makeSound() {
        System.out.println("Vroom, Vroom");
    }

    public int howLoud() {
        return volume;
    }
}
package interfaces;

/**
 * The Dolphin class implements both the MakesSound and Swims interfaces.
 
 @author Grant Braught
 @author Dickinson College
 @version Aug 20, 2009
 */
public class Dolphin implements MakesSound, Swims, Comparable<Dolphin> {

    private int length; // in feet.

    public Dolphin(int length) {
        this.length = length;
    }

    public int getLength() {
        return length;
    }

    // === Implementation of the MakesSound interface ===

    public void makeSound() {
        System.out.println("Squeek Squeek");
    }

    public int howLoud() {
        return 2;
    }

    // === Implementation of the Swims interface ===

    public void swim() {
        System.out.println("Shaking my tail, Shaking my tail");
    }

    // === Implementation of the Comparable interface 

    /**
     * Implementation of the compareTo method specified by the Comparable
     * interface.
     
     <p>
     * This method returns:
     <UL>
     <LI>a positive value (+1) if this Dolphin is longer than dol (i.e. comes
     * after it in sorted order.)
     <LI>0 if this Dolphin and dol have the same length
     <LI>a negative value (-1) if this Dolphin is shorter than dol (i.e. comes
     * after it in sorted order.)
     </UL>
     */
    public int compareTo(Dolphin dol) {
        if (this.getLength() > dol.getLength()) {
            return +1;  // this dolphin is longer than dol.
        }
        else if (this.getLength() == dol.getLength()) {
            return 0;   // this dolphin is the same length as dol.
        }
        else {
            return -1;  // this dolphin is shorter than dol
        }
    }
}
package interfaces;

/**
 * The Duck class implements both the MakesSound and Swims
 * interfaces.
 *
 @author Grant Braught
 @author Dickinson College
 @version Aug 20, 2009
 */
public class Duck implements MakesSound, Swims {

    private String species;
    
    public Duck(String species) {
        this.species = species;
    }
    
    public String getSpecies() {
        return species;
    }
    
    // === Implementation of the MakesSound interface ===
    
    public void makeSound() {
        System.out.println("Quack, Quack");
    }
    
    public int howLoud() {
        return 4;
    }

    // === Implementation of the Swims interface ===
    
    public void swim() {
        System.out.println("Paddling my feet, Paddling my feet");
    }
}
package interfaces;

import java.util.Random;

/**
 * A collection of sample code that illustrates different aspects of the use of
 * interfaces in Java.
 
 @author Grant Braught
 @author Dickinson College
 @version Aug 20, 2009
 */
public class InterfaceExamples {

    /**
     * This method illustrates the use of objects that implement an interface
     * via a reference of their own object type.
     */
    public static void UsingObjectTypes() {
        Car c = new Car("Ford"5);
        System.out.println("Car:");
        System.out.println(c.getMake());
        c.makeSound();
        System.out.println(c.howLoud());

        Duck d = new Duck("Mallard");
        System.out.println("Duck:");
        System.out.println(d.getSpecies());
        d.makeSound();
        System.out.println(d.howLoud());
    }

    /**
     * This method illustrates the use of objects that implement an interface
     * via a reference of their interface type.
     */
    public static void UsingInterfaceTypes() {
        Car c = new Car("Ford"5);
        MakesSound ms = c;

        /*
         * We can invoke the makeSound and howLoud methods using a reference of
         * type MakesSound because those methods are defined in the MakesSound
         * interface.
         */
        System.out.println("MakesSound Reference");
        ms.makeSound();
        System.out.println(ms.howLoud());

        /*
         * The following line is illegal because the getMake method is not part
         * of the MakesSound interface.
         */
        // System.out.println(ms.getMake());   
    }

    /**
     * This method accepts two objects that implement the MakesSound method and
     * returns whichever object makes the louder sound.
     
     @param obj1 an object that implements MakesSound
     @param obj2 another object that implements MakesSound
     @return the object that makes the louder sound.
     */
    public static MakesSound whoIsLouder(MakesSound obj1, MakesSound obj2) {
        if (obj1.howLoud() >= obj2.howLoud()) {
            return obj1;
        }
        else {
            return obj2;
        }
    }

    /**
     * Call the whoIsLouder method with objects of different types and print
     * out the sound made by whichever object is louder.
     */
    public static void printLouderSound() {
        /*
         * Call whoIsLouder with obj1 being a Duck and obj2 being a Car.
         */
        Duck d1 = new Duck("Mallard");
        Car c1 = new Car("Ford"5);
        MakesSound ms1 = whoIsLouder(d1, c1);
        ms1.makeSound();

        /*
         * Call whoIsLouder with obj1 being a Dolphin and obj2 being a Duck.
         */
        Dolphin do1 = new Dolphin(12);
        Duck d2 = new Duck("Wood");
        MakesSound ms2 = whoIsLouder(do1, d2);
        ms2.makeSound();

        /*
         * The following is illegal because the class String does not implement
         * the MakesSound interface.
         */
        //String p1 = "bob";
        //MakesSound ms3 = whoIsLouder(p1,d1);
    }

    /**
     * Call the whoIsLouder method with objects of different types and print
     * out information about whichever object is louder (e.g. the make of 
     * a Car, or the species of a Duck).
     */
    public static void printLouderInfo() {
        Duck d1 = new Duck("Bufflehead");
        Random rnd = new Random();
        Car c1 = new Car("Porche", rnd.nextInt(10));
        
        /*
         * We get back an object that implements MakesSound but we don't
         * know if it is a Car object or a Duck object.
         */
        MakesSound ms = whoIsLouder(d1,c1);
        
        /*
         * Use instanceOf to determine the type of the object so that
         * we can type cast it to the correct type.
         */
        if (ms instanceof Car) {
            Car c2 = (Car)ms;
            System.out.println("The " + c2.getMake() " is louder.");
        }
        else if (ms instanceof Duck) {
            Duck d2 = (Duck)ms;
            System.out.println("The " + d2.getSpecies() " is louder.");
        }
        else {
            System.out.println("Humm, neither a Car nor a Duck!");
        }
    }

    /**
     * Main method that allows each of the example methods to be run.
     
     @param args none
     */
    public static void main(String[] args) {
        System.out.println("usingObjectTypes:");
        UsingObjectTypes();

        System.out.println();
        System.out.println("usingInterfaceTypes:");
        UsingInterfaceTypes();

        System.out.println();
        System.out.println("printLouderSound:");
        printLouderSound();
        
        System.out.println();
        System.out.println("printLouderInfo:");
        printLouderInfo();
    }
}
package interfaces;

/**
 * An interface implemented by objects that can make sounds.
 
 @author Grant Braught
 @author Dickinson College
 @version Aug 20, 2009
 */
public interface MakesSound {

    /**
     * Print out the sound that is made by the object.
     */
    void makeSound();

    /**
     * Get a number from 1 to 10 indicating how loud the sound is that is made
     * by the object.
     
     @return the volume of this object's sound.
     */
    int howLoud();
}
package interfaces;

import java.awt.event.*;
import javax.swing.*;

/**
 * Demonstration of the Timer class that is able to repeatedly invoke the
 * actionPerformed method on any object that implements the ActionListener
 * interface.
 
 @author Grant Braught
 @author Dickinson College
 @version Aug 20, 2009
 */
public class MyTimerEvent implements ActionListener {

    /*
     * The actionPerformed method is invoked each time the Timer goes off.
     */
    public void actionPerformed(ActionEvent e) {
        /*
         *  This just prints a message, but in practice you could do anything 
         *  that you want here.
         */
        System.out.println("Here we go again...");
    }

    /**
     * Use a Timer to print out a message once every second.
     
     @param args none
     */
    public static void main(String[] args) {
        // Create and start the timer.
        Timer t = new Timer(1000new MyTimerEvent());
        t.start();

        // This is just a way to wait until the user has seen enough.
        JOptionPane.showMessageDialog(null, "Click me to quit");

        // Stop the timer.
        t.stop();
    }
}
package interfaces;

import java.util.*;

/**
 * Demonstration of the Arrays.sort method that is able to sort objects that
 * implement the Comparable interface.
 
 @author Grant Braught
 @author Dickinson College
 @version Aug 20, 2009
 */
public class SortingDolphins {

    /**
     * Create an array of 10 Dolphins with random lengths, print them out, sort
     * them and then print them again to show that they are now in sorted order
     * by length.
     
     @param args none
     */
    public static void main(String[] args) {
        System.out.println("Sorting Dolphins:");
        
        // Create an array of 10 random length Dolphins.
        Dolphin[] dolphins = new Dolphin[10];
        Random rnd = new Random();
        for (int i = 0; i < 10; i++) {
            dolphins[inew Dolphin(rnd.nextInt(20));
        }

        // Print out the Dolphin's lengths before sorting them.
        System.out.print("Before: ");
        for (Dolphin d : dolphins) {
            System.out.print(d.getLength() " ");
        }
        System.out.println();

        /*
         * Sort the Dolphins based upon the compareTo method in the Dolphin
         * class.
         */
        Arrays.sort(dolphins);

        // Print out the Dolphin's lengths after sorting them.
        System.out.print(" After: ");
        for (Dolphin d : dolphins) {
            System.out.print(d.getLength() " ");
        }
        System.out.println();
    }
}
package interfaces;

/**
 * An interface implemented by objects that can swim.
 
 @author Grant Braught
 @author Dickinson College
 @version Aug 20, 2009
 */
public interface Swims {

    /**
     * Print out a message indicating how the object swims.
     */
    void swim();
}