Index

Let's try using some interfaces to see if it helps with our failed first try.

Review of Failure Point


We'll first review our failure point, and solve the problem from that point down.

Failure Point
Recall: "Object" does not understand "printOn".

We simply need something that does understand "printOn". That would solve this problem.

As coders, the nice thing is when we need a new class to do something, we can simply code it up.
public void printFullReport(PrintStream report)  {
	/*Compile error, "printOn not understood by Object
	for (Object each: this.list)
		each.printOn(report);		//<---------- compile error here
	*/
	report.println("College: " + this.name);
	report.println("Apologies, printing of list is not yet supported");
	report.println("Objects do not understand \"printOn\"");
}

A New Tool: Interface


A Java interface is very much like a class from the usage perspective. As a matter of fact, let's generalize class and interface, and just think of them both as "types". E.g. example "types" might be: List, String, Rectangle, Professor, etc.

Propose a New Type


Failed attempt: On the left "Object" does not understand "printOn". 😕
What we need: A type that understands "printOn".
Solution: On the right new type "Printable". We will create "Printable" such that it understands "printOn". 👍🏽
public void printFullReport(PrintStream report)  {
	/*Compile error, "printOn not understood by Object
	for (Object each: this.list)
		each.printOn(report);		//<---------- compile error here
	*/
	report.println("College: " + this.name);
	report.println("Apologies, printing of list is not yet supported");
	report.println("Objects do not understand \"printOn\"");
}
public void printFullReport(PrintStream stream)  {
	//printOn is understood by Printable dudes, so we're good to go
	stream.println("College: " + this.name);
	stream.println("I have a list of entities of size: " + this.list.size());
	stream.printf("%nHere is my list:%n%n");
	for (Printable each: this.list)
		each.printOn(stream);
}


Design the New Type


The first cut at our proposed type is that it is named Printable, and we know it must understand this method:
public void printOn(PrintStream report)


Use Common Superclass?


Please recall from the code requirements that the family of objects may include classrooms, computers, parking lots, professors, etc (and many other varied types). Because these classes are really not similar (e.g. ParkingLot and Professor), we decide we can not add a common superclass.

Note: We can not add "printOn" to class "Object". Java will not allow changes to system classes.

A Simple Interface?


Printable Interface
Here is the code for the "Printable" interface. Please note the similarity to a "class" except:
  • The word "interface" is used instead of "class"
  • Method code (body) is not present (just the method header).

It is like a shell of a class. It's simple and we like simple.
public interface Printable {
	public void printOn(PrintStream report);
}


Implementing the Interface


Now that we have a new type (interface) we need to tweak our classes so they "implement" the interface.

Classroom2
  • We simply add "implements Printable" to the class header
  • We must have a method with a method header matching that in the interface.

Now:
  • Classroom2 "is-a" Printable
  • Classroom2 understands the method "printOn"

We do similar for Professor2 as shown here...
#1
public class Classroom2 implements Printable { private int roomNumber; public Classroom2(int aRoomNumber) { this.roomNumber = aRoomNumber; } public int getRoomNumber() { return roomNumber; }
#2
public void printOn(PrintStream report)
{ report.println("I am Classroom: " + getRoomNumber()); } }
College2
Now back to class "College2".

  • This is the method where the bug bit us in try #1.
  • It now works! 😊 The method "printOn" is understood by Printable.
#1
public void printFullReport(PrintStream stream)
{ //printOn is understood by Printable dudes, so we're good to go stream.println("College: " + this.name); stream.println("I have a list of entities of size: " + this.list.size()); stream.printf("%nHere is my list:%n%n"); for (Printable each: this.list)
#2
each.printOn(stream); }

Completed Code


Here are the classes for reference as we go through the example.

Conclusion


"Try 2" succeeded! By adding a simple interface with only one method, we were able to easily solve the problem! 😊