06b: Java: Interfaces and Inheritance

ICS211, Fall 2012
Dr. Zach

(switch view)

Status check

Interface

interface

Example: Challenge

public interface Challenge {
  public int getXP();
}

Implementing Challenge interface

public class Treasure implements Challenge {
  ...
}

public class Monster implements Challenge, Destructable, ... {
  ...
}

Compiler will force each of these classes to implement a public int getXP() method.

Challenge variables

Comparable

Circle: Implementing Comparable

public class Circle implements Comparable<Circle> {
  private int radius;
  
  public Circle(int radius) {
    this.radius = radius;
  }
  
  public int compareTo(Circle c) {
    //sort by increasing size
    if (this.radius < c.radius) {
      return -1;
    }else if (this.radius > c.radius) {
      return 1;
    }else {
      return 0;
    }
  }
  
  //...
  
  public String toString() {
    return "Circle(" + this.radius + ")";
  }
}

Could have implemented this compareTo method in one line:

return this.radius - c.radius;

Using the compareTo method

Circle big = new Circle(50);
Circle mid = new Circle(20);
Circle small = new Circle(5);

if (small.compareTo(big) < 0) {
  System.out.println("Small circle comes before big circle");
}
if (mid.compareTo(big) == 0) {
  System.out.println("mid and big are the same size");  
}

Circle[] circles = {mid, small, big};
java.util.Arrays.sort(circles);
System.out.println(java.util.Arrays.toString(circles));
//prints: [Circle(5), Circle(20), Circle(50)]

Longer interfaces possible

public interface Collection<E> {
  public void add(E item);
  public E get();
  public E remove();
  public int size();
}

Implemented by Stack

public class Stack<E> implements Collection<E> {

  //...existing Stack implementation here...

  public void add(E item) {
    this.push(item);
  }

  public E get() {
    return this.peek();
  }
  
  public E remove() {
    return this.pop();
  }

  //size method already exists
}

Using it

Collection<String> c = new Stack<String>();
Collection<String> other = new Queue<String>():
c.add("Alice");
c.add("Bob");
c.remove();
System.out.println(c.get());
System.out.println(c.size());

//NO: c.push("Carol")
//NO: c.peek()

Summary of Interfaces

Inheritance

Example

public class Animal {
  public void speak() {
    System.out.println("The animal vocalizes.");
  }
}

public class Dog extends Animal {
  public void speak() { 
    System.out.println("Woof! Woof!");
  }
  
  public void fetch(Ball b) {
    //????
  }
}

public class SmallDog extends Dog {
  public void speak() { 
    System.out.println("Yip! Yip! Yip!");
  }
}

public class Cat extends Animal {
  public void speak() {  
    System.out.println("Meow.");
  }
}

public class Fish extends Animal {
}

public class Ball { 
}

Class hierarchy: super/parent class vs sub/child class relationship

Inheritance and Overriding

Animal a = new Animal();
Dog dog = new Dog();
SmallDog pom = new SmallDog();
Cat cat = new Cat();
Fish fish = new Fish();

Basically, starts at most specific class and works up until it finds a definition to execute.

Polymorphism

Animal beast = new Fish();
beast.speak();  //prints? 
Dog dog = new SmallDog();
dog.speak();  //prints?

Animal[] zoo = {new Dog(), new SmallDog(), new Cat(), new Fish()};
for (Animal a : zoo) {
  a.speak();
}

Animal rex = new Dog();
//NO: rex.fetch(new Ball());

Casting

Top of the Hierarchy: Object

toString()

Default equals method

//assuming earlier Circle definition
Circle one = new Circle(10);
Circle two = new Circle(10);
Circle tu = two;
System.out.println(one == two);      //false
System.out.println(tu == two);       //true
System.out.println(one.equals(two)); //false
System.out.println(tu.equals(two));  //true

Custom equals method

public class Circle implements Comparable<Circle> {
  //... earlier definition...
  
  public boolean equals(Object obj) {  //note the Object
    if (obj instanceof Circle) {  //also catches null
      Circle circle = (Circle) obj;
      return this.radius == circle.radius;
    }
    return false;
  }
}
Circle one = new Circle(10);
Circle two = new Circle(10);
Circle tu = two;
System.out.println(one.equals(two)); //true
System.out.println(tu.equals(two));  //true

Failure to override

@Override annotation

  @Override
  public String toString() {
    //...
  }
  @Override public boolean equals(Circle e) {
    //...
  }

super keyword: Methods

super keyword: Constructors

public class Rectangle {
  
  private int width;
  private int height;
  
  public Rectangle(int width, int height) {
    this.width = width;
    this.height = height;
  }
  
  //...
}
public class Square extends Rectangle {

  public Square(int side) {
    super(side, side);  //actually required
  }
}

protected

Abstract classes

For next time