Copyright (C) 2002 Katrin Becker Version II - 2002 Last Modified September 8, 2005 10:47 AM
Interfaces

Image and notes reference: http://www.javaworld.com/javaworld/jw-12-1998/jw-12-techniques.htm
Introduction to 'implements'
C++ allows multiple inheritance, Java does not.
Inheritance allows a class to inherit properties from a parent (super)class.
The analogy used is that of inheriting genes.
Multiple inheritance allows a class to inherit properties from more than one class. The can stretch the analogy.
The diamond problem:
Can we imagine a cross between two quite different classes - between a frog and a dinosaur?
In Jurassic Park, scientists combine dinosaur DNA with DNA from modern frogs to get an animal that resembled a dinosaur but in some ways acted like a frog. At the end of the novel, the heros of the story stumble on dinosaur eggs. The dinosaurs, which were all created female to prevent fraternization in the wild, were reproducing. Chrichton attributed this miracle of love to the snippets of frog DNA the scientists had used to fill in missing pieces of the dinosaur DNA.
The diamond problem can arise in inheritance hierarchies like the one shown in above. In fact, the diamond problem gets its name from the diamond shape of such an inheritance hierarchy.
One way the diamond problem can arise in the Jurassic Park hierarchy is if both Dinosaur and Frog, but not Frogosaur, override a method declared in Animal. Here's what the code might look like if Java supported traditional multiple inheritance:
abstract class Animal

{

abstract void talk();

}



class Frog extends Animal

{

void talk() {

System.out.println("Ribit, ribit.");

}



class Dinosaur extends Animal

{

void talk()

{

System.out.println("Oh I'm a dinosaur and I'm OK...");

}

}



// (This won't compile, of course, because Java

// only supports single inheritance.)

class Frogosaur extends Frog, Dinosaur

{

}

The diamond problem rears its ugly head when someone tries to invoke talk() on a Frogosaur object from an Animal reference, as in:
Animal animal = new Frogosaur();
animal.talk();
Because of the ambiguity caused by the diamond problem, it isn't clear whether the runtime system should invoke Frog's or Dinosaur's implementation of talk(). Will a Frogosaur croak "Ribbit, Ribbit." or sing "Oh, I'm a dinosaur and I'm okay..."?
The diamond problem would also arise if Animal had declared a public instance variable, which Frogosaur would then have inherited from both Dinosaur and Frog. When referring to this variable in a Frogosaur object, which copy of the variable -- Frog's or Dinosaur's -- would be selected? Or, perhaps, would there be only one copy of the variable in a Frogosaur object?
In Java, interfaces solve all these ambiguities caused by the diamond problem. Through interfaces, Java allows multiple inheritance of interface but not of implementation. Implementation, which includes instance variables and method implementations, is always singly inherited. As a result,confusion will never arise in Java over which inherited instance variable or method implementation to use.
Java's interface gives you more polymorphism than you can get with singly inherited families of classes, without the "burden" of multiple inheritance of implementation.

Polymorphism?
The quality or state of assuming different forms (or shapes)
A different analogy - we can learn things. We have only one parent, who we inherit from, but can learn about many other things.
You may not want to cross a cat with a dog after all - you may want a cat with a Ô fetchÕ interface.
Thus we could have a class inherit from your parent class, while knowing about the mouse and keyboard.


This is how Java allows classes to know about some devices (like the mouse and the keyboard)

Java has a special kind of class it calls an INTERFACE.



Making your own interfaces:
Consider a general sorting routine; class Sortable, having the method compare as an abstract comparison method for items. We can now define subclasses of Sortable (i.e. Student) and sort Student-type objects.
However, the registrar already has a student class based on some other class, rooted in a File object. We cannot have a Student defined on multiple classes.
A Java interface is a promise made by the programmer to implement certain specific methods, as outlined in the specific interface documentation. The keyword implements states this promise, and Java checks.

public interface Sortable

{

public int compare(Sortable b);

}

The above states that any class implementing the Sortable interface must provide a method named compare defined as above.
Now to use this, we take the old definition of student:
class Student extends parallelBinaryFile

{

...

}

and define it is using the Sortable interface:

class Student extends parallelBinaryFile implements Sortable

{

public int compare (Sortable b)

{ ... }



...

}

No static methods are allowed in interfaces.





Using pre-defined interfaces -
Need to know about EVENTS!
The Java 1.1 event model
Code for 16-Puzzle
(1.0 and before is different: simpler and not flexible)
Uses delegation. Objects interested in an event are called listeners. Each type of event requires a specific listener interface, a set of methods called when that event occurs (like a Motif/X callback). A listener must be registered with the source of the event (by using the addListener method).
As an example, let's look at a Button, which has a quite obvious set of needs. First, we need to know a few things.
Button events are ActionEvents (their class name), and a class that uses buttons must implement the ActionListener interface. This simply means coding the method named actionPerformed; this is called when the button is pressed.

The basic steps are: create the Button object, add it to the Frame (a container), add the Frame to the listeners of the Button, and implement the actionPerformed method (to do whatever is wanted when the Button is pressed).

// Trivial frame with Button: EG event handler
// JP 1999-10-01 Written, tested.

import java.awt.*;
import java.awt.event.*;

public class buttonTest extends Frame implements ActionListener
{
private Button b, c;

buttonTest ()
{
int height, width;

setLayout (null);
setTitle ("Event demo");
// Size this window and place components.
height = 200;
width = 200;

b = new Button ("Jim");
add(b);
b.addActionListener (this);
b.setSize (30, 30); // Component: button size
b.setLocation(new Point(30,30)); // location.

c = new Button ("Quit");
add(c);
c.addActionListener (this);
c.setSize (30, 30); // Component: button size
c.setLocation(new Point(90,30)); //Location

setSize (width, height);
show();
}

public void actionPerformed (ActionEvent e)
{
String s = e.getActionCommand();

if ("Jim".equals(s))
{
System.out.println ("Pressed button.");
}
else if ("Quit".equals(s))
{
System.out.println ("Quitting now.");
System.exit(0);
}
}

// TEST MAIN
public static void main (String args[])
{
buttonTest test = new buttonTest ();
}
}


Copyright (C) 2002 Katrin Becker Version II - 2002 Last Modified September 8, 2005 10:47 AM