RU beehive logo ITEC dept promo banner
ITEC 120
2010fall
ibarland

homeinfolectslabsexamshws
tutor/PIsbreeze (snow day)
Object120 + its docsjava.lang docsjava.util docs

lect14c
3 uses of inheritance

Review inheritance

Three Applications of Inheritance

Based on hw10—gRUe solution, we give three ways to refactor it and make it more flexible, all using inheritance.

While each of the above three improvements can be done in different ways (and sometimes w/o introducing new classes), it's more cleanly done with inheritance and classes. There is an adage in software architecture:

If your program is becoming too complicated, add more classes.

You can see Wikipedia (or other books) on other examples of these “software design patterns”, or others. (In particular, I find the delegate pattern quite useful in practice.)


Interface vs. abstract class (optional)

  1. Like an abstract class, interfaces are useful only for extending; you can't make an instance of the interface itself.
  2. An interface is like a class except that it contains no code -- it only has method signatures (and static final constants).
  3. By comparison, an (abstract) class can contain fields and actual code, which gets shared.
  4. A class can only extend one superclass (in Java).
  5. A class can implement many interfaces.
(ii) and (iii) are advantages to abstract classes, but (iv) and (v) are an advantage to interfaces. We'll come back to this topic below, trying to get the best of both worlds.

Example: Suppose we want to sort a list of PizzaServers by salary (ascending). We write some complicated to do so (perhaps after taking ITEC 220); it will involve statements like

  List<PizzaServer> sort( List<PizzaServer> employees ) {
    // ...code, perhaps including loops...

    Employee itm1 = employees.get();
    Employee itm2 = employees.get();

    if (itm1.getSalary() < itm2.getSalary()) 

    // ...
    }
(where t1 and t2 are local variables, perhaps inside a loop).

Then, later, we want to sort a list of Dogs, by age (ascending). This is practically the same problem; the only difference is that this version will involve statements like if (itm1.getAge() < itm2.getAge()) , (where itm1 and itm2 are now Dogs instead of PizzaServers). Yech! … nearly-repeated-code which is impossible to factor out because one deals with getWeight and another with getAge.

the Comparable interface

Interfaces, to the rescue! In particular, the the java.lang.Comparable interface. If both Dogs and PizzaServerss implement the interface, then our sorting code can include

  if (itm1.compareTo(itm2) < 0) /* think: "itm1 < itm2" */ 
Then, all that remains is telling Java how to compare two Dogs -- in our case, by increasing age:
class Dog implements Comparable<Dog> {
  //... other Dog fields/methods

  public int compareTo( Dog other ) {
    if (this.getAge() < other.getAge()) {
      return -1;  // Any negative number is good enough to satisfy the interface.
      }
    else if (this.getAge() == other.getAge()) {
      return 0;
      }
    else if (this.getAge() > other.getAge()) {
      return +1;  // Any positive number will suffice.
      }
    else {
      System.err.println( "Shouldn't reach this far." );
      return 0;  // Better than returning a bad answer: Throw an exception.
      }
    }
    
  }
(Challenge: Can you find a one-line way to implement this method?)
Similarly, PizzaServers would have a similarly have a method compareTo which captures the notion “by increasing salary”.

In fact, we could sort songs alphabetically-by-artist: we'd have the Song method compareTo which returns a negative number if the artist's name comes alphabetically before the artist of another song. How can we tell if one String is before another, alphabetically? Fortunately, class String implements Comparable itself!

Practice Write compareTo for Songs, so that it compares alphabetically by artist.

Practice If class String didn't implement Comparable, how would we figure out whether one String comes before another alphabetically?
Hint: use a loop, and compare individual chars with >2

Note that we don't want to have these two classes both inherit from some common superclass, each overriding compareTo appropriately. You might argue that perhaps class Object should've had including compareTo in the same way they already included toString and equals. However, there will always be new behaviors which people might want in the future, so having interfaces gives us, as programmers, a power different from abstract classes.

Exercise How do we need to modify class PizzaServer, so that it implements Comparable?

Once a class implements Comparable, we can sort a list of them:

java.util.List<PizzaServer> employees = new java.util.LinkedList<PizzaServer>();
// ... add to the list...

employees.toString();
// `sort` is a static method; only compiles if PizzaServer implements Comparable:
java.util.Collections.sort( employees );  
employees.toString();

Another example of interfaces: java.util.List is an interface, which is implemented by LinkedList, as well as a class named ArrayList.3 This means that if we change the signature int numCoversOn( LinkedList<Song> otherSongs ) to int numCoversOn( List<Song> otherSongs ) then our function will be able to handle both LinkedLists, as well as ArrayLists, as well as any other List variant people might invent in the future!


1In some languages, code is a first-class value which can be passed around, stored in fields, etc.. In othose languages, we wouldn't even bother calling this a 'command pattern'; we'd just have a structure whose field was code.      

2You can also subtract one char from another, and then compare the result (as an int) to zero.      

3 (Its name is a bit confusing; an ArrayList is not an array! It's a List, since it can get(index) and add and answer size() and isEmpty(). That is, it implements the List interface, so therefore an ArrayList is a List. You can't use square-brackets or the field length with ArrayList. It derives its name from the fact that under the hood, it uses arrays to help it organize its contents. But we don't care about how it works, as long as it meets its interface.      

homeinfolectslabsexamshws
tutor/PIsbreeze (snow day)
Object120 + its docsjava.lang docsjava.util docs


©2010, Ian Barland, Radford University
Last modified 2010.Dec.11 (Sat)
Please mail any suggestions
(incl. typos, broken links)
to iba�rlandrad�ford.edu
Powered by PLT Scheme