Interface vs. Abstract in Java

Or: Why does javac tell me my class should be declared Abstract?

If you got here because your java compiler is telling you your class should be declared abstract, let's clear that up first, then we can go into the theory behind Interface vs. Abstract.

Let's say you get this error:

SelectSort.java:6: SelectSort should be declared abstract; it does not define sort(jds.Indexed) in SelectSort
public  class SelectSort implements SortAlgorithm
        ^
1 error

What's happening here is that, as usual, javac's misleading error messages confuse and obfuscate things. What this means is that you're using the "implements SortAlgorithm" phrase, which tells the compiler that you want the resulting class to be marked as providing all of the methods defined in the "SortAlgorithm" interface. However, you apparently have not included code in your class to implement the "sort(jds.Index)" method.

What javac should really say is:
"Hey you! You said "implements SortAlgorithm", but you left out one of the methods of SortAlgorithm, the method "sort(jds.Indexed). So either implement sort(jds.Indexed) in your SelectSort class, or add the keyword "abstract" (before class) so I know you weren't intending to fully implement SortAlgorithm."

So the answer to your immediate problem is to go in and impelement sort(jds.Indexed).

What implications does declaring a class abstract have?

For your uses, you almost never want to use abstract classes. If you're in a class (well, a school type class, not a java type class :-). and you instructor tells you to make your class extend a certain abstract class, what that means is that the abstract class left one or more methods unimplemented. Because you're extending the abstract class instead of implementing an interface, all you have to do is implement the missing bits.

So what's the difference between an Interface and an Abstract Class?

An interface is a conceptual thing, though it does have concrete implications in Java.

You can't discuss Interfaces and Abstract Classes without first defining what a Class is. By the time you get here, you should know what a Class in java is, but just to recap, the concept of a class in OOP is that it's the description of the common structure and behavior of a set of objects in a system.

Often it's useful to look at this sort of thing and separate out the description of how you interact with the class (i.e. what methods does it have, what class variables does it have - in other words, the interface) from the implementation of the class. There are various good reasons to do this. Sometimes you want different classes to play the same role but you can't just make them be children of the same parent class. Sometimes you want to allow for the possibility of different vendors to supply different implementations.

In general the word "interface" means what you use to interact with something (well, okay, originally it meant "a surface forming a common boundary of two bodies, spaces, or phases" (Merrian-Webster Collegiate Dictonary), but the computer people stole that word).

For example:
Let's say you have a class named User.
You want to build a new class, named Robot.

You don't necessarily want the Robot to be descended from User, or vice versa, but you do want other code to be able to talk to the Robot just as if it were a user. So you make sure Robot has all the same method names and takes the same arguments as User, and sends back the same types of responses.

Problem solved for now, but what if you want to possibly add more classes in the future? What if you don't want *all* of User's stuff on Robot, just some stuff? What if somebody else adds a new class that claims to be the same sort of class, claims to have all the right methods and arguments, etc, but you want to make sure?

The Answer: you define an interface for all things that you can interact with like a person in your program, let's say we call it an "Interactor". In Java, an interface is sort of passive - not like code. It just defines a set of method names, what the argument types are, and what the return types are. In other words, it defines the interface that the rest of the program will use to talk to that class.

The interface should define some common set of these methods, the ones that you'll want all Interactors to have. Then in your User and Robot classes, you add the phrase "implements Interactor" to the class definition. This tells the Java compiler to check and make sure that you've got code for all the methods in the interface, and to add the interface identifier to the class file.

Then, at some later point in time when a program loads one of your class files in, and tries to use it as an Interactor, the java environment will automatically check to see whether that class "implements Interactor" (aka has the "implements Interactor" phrase in the definition and has actual method code for all the methods).

Abstract Class

Okay, so that's an interface. Then what's an abstract class?

An abstract class is more of a functional thing than an interface. Abstract classes are for implementation - a shortcut that comes in handy during the implementation stage but which should be largely ignored during the design stage.

But let's take another case - let's say that for some reason you decide you do want Robot and User to share the same parent. All the code for the different methods is the same and you'd rather avoid having two sets of it. Okay, so you make a common superclass, let's call it "Actor" (as in something that acts within the program). You put all the common code on the Actor class and you make Robot and User descend from it (by adding the "extends Actor" phrase to their class definitions).

But wait a minute... the Actor class by itself isn't really enough to be instantiated and used. Plus, you have some methods that you know _should_ be there but you can't define them yet. In fact there are some methods that you want the Actor methods to be able to count on having access to. You want to make sure any descendents of Actor define them. So you add the declaration for these methods, plus the Abstract keyword.

Now the Java compiler will spot the "Abstract" keyword and not let anybody directly instantiate and use this class. But you can use it as a basis for extending.

Further Reading:

In general I strongly recommend anybody starting out with Java to go to www.bruceeckel.com and download the book, or better yet, to save your eyes, visit your nearest bookstore and buy a printed copy.