Return to lecture notes index

15-100 Lecture 13 (Friday February 11, 2005)

Interfaces and Implementing Them

Interfaces allow us to create a specification that sets the standards of what signature a method should have. If a class wants to implement (or use) an interface the class must contain all of methods and their signatures listed in the interface. This allows us to make everything uniform across classes as to how to call a method (example: for a compareTo method you have to pass in an Object and a int will be returned). Interfaces are like industry standards. The communications industry has one standard so that all TV components can interact with or be connected to each other (it would be really annoying if a new DVD player could only connect with one brand of TV). Here's the Comparable interface:


interface Comparable {
   public int compareTo(Object o);
}
So now that we have the interface, let's implement it. But what does "implement" mean? To java "implements" means track down the named class's interface (in this case Comparable). Java will then make sure that the programmer wrote all of the interface's methods and fulfilled the method's signatures. Java will guarantee that the interface will be correctly fulfilled (if it isn't the compiler will create a complier error).

class PriceTag implements Comparable {
   public int compareTo(Object o){
      ...
      return blah; //where blah is 0 if the PriceTag's are equal, or  a negative int 
                   //if "o" is bigger, or a positive int if "this" is bigger.
   }

   public static void main(String [] args){
      PriceTag pt = new PriceTag(...);

      Comparable comp1 = new PriceTag(...);//this is a legitimate way of storing a reference 
      Comparable comp2 = new PriceTag(...);//to a PriceTag.  Because Comparable is a 
                                           //superclass of PriceTag a variable of type 
                                           //Comparable can hold a PriceTag reference
                                           //(which is a subclass of Comparable)
      comp1.compareTo(comp2); //this will compare comp1 ("this") to comp2 ("o")
                              //and return an int
   }
}
Cascading if's

Cascading if's are a series of nested if's and else's so that you only go into a condition if the previous cases are false. This saves your computer some runtime because you cut down on how many comparisons it has to make as the program runs. However, computer time is cheap...programmer time isn't. Unless you are making a program where running time is important (such as adjusting the flaps on an airplane's wings in order to keep the craft air born) you should strive to make your code as readable as possible. All of the indentation makes the code a little harder to read and it takes longer to analyze when the computer will be allowed to enter a specific nested for statement. Thus you should try to avoid long, complex cascading if statements when possible. Here is an example of cascading if's:

  
class ProductForSale {
  private String productName;
  private double priceInDollars; //eg $12.34 is 12.34
  private int quantityOnHand;

  //note the capitalization (first letter is capitalized, like in a class name)
  //this also has no return type ... these two clues signal that this is a constructor 
  public ProductForSale(String productName, double priceInDollars, int quantityOnHand) {
    this.productName=productName;
    this.priceInDollars=priceInDollars;
    this.quantityOnHand=quantityOnHand
  }

  public String toString(){
    return productName + ": $" + priceInDollars + ", "+ quantityOnHand;
  }

  //note we are making use of the class we made on Wednesday
  public boolean purchase(int quantityToBuy, Wallet w) {
    if ((quantityToBuy<=0)||(quantityOnHand<=0))
      return false;
    if (quanityToBuy*priceInDollars > w.getAmountOfCashInDollars)
      return false;
    if (quantityOnHand > quantityToBuy)
      return false;
    
		//if we haven't already left the method then make the purchase...
    quantityOnHand -= quantityToBuy //quantityOnHand = quantityOnHand-quantityToBuy
    w.spendCash(quantityToBuy*priceInDollars;
    return true;
  }
}
Here's another way to code the above method (using cascading if's)...

  public boolean purchase(int quantityToBuy, Wallet w) {
    if (quantityToBuy<=0)
      return false;
    else{
      if (quantityOnHand <= 0)
        return false;
      else{
        if(quanityToBuy*priceInDollars > w.getAmountOfCashInDollars)
          return false;
        else{
          if (quantityOnHand > quantityToBuy)
            return false;
          else{
            quanityOnHand -= quantityToBuy //quantityOnHand = quantityOnHand-quantityToBuy
            w.spendCash(quantityToBuy*priceInDollars;
            return true;
          }
        }
      }
    }
  }

As you can see this is a little hard to read and understand. If you do want to use a cascading structure an easier way to write it would be...

  public boolean purchase(int quantityToBuy, Wallet w) {
    if (quantityToBuy<=0)
      return false;
    else if (quantityOnHand <= 0)
      return false;
    else if(quanityToBuy*priceInDollars > w.getAmountOfCashInDollars)
      return false;
    else if (quantityOnHand > quantityToBuy)
      return false;
    else{
      quanityOnHand -= quantityToBuy //quantityOnHand = quantityOnHand-quantityToBuy
      w.spendCash(quantityToBuy*priceInDollars);
      return true;
    }
  }
Notice how in this version of the cascading if's I merely took out the return between the else and the next if statement. The previous method made it easier to see which else belonged to which if. However this form of the code is easier to read. Also the "else if" implies that this statement will only be reached if all of the previous statements are false.