
Normal, or concrete, classes in Java can be instantiated using the new keyword. Concrete classes both define the functionality, that is what the class does, and the interface, that is what methods are available for you to call. Most of the classes you write will be concrete classes like the one below.
public class MyConcreteClass {
public void perform() {
...
}
}
At the other end of the spectrum we have an interface which only defines which methods we can call on it – there is no functionality in there. The interface in the example below specifies that a class implementing the interface will at least have the 4 listed methods. Notice that there is no method bodies (the compiler will enforce this).
public interface Car {
public void increaseSpeed();
public void decreaseSpeed();
public void turnRight();
public void turnLeft();
}
By creating a class and inserting the keyword “abstract” after the class visibility modifier (public, private, “friendly”) makes the class into an abstract class. An abstract class is somewhere in between an interface and a class, that is a class where some of the functionality is specified but not all. Think of an abstract class as a class with some blanks that needs to be filled in by any, non-abstract, class that extends it. An abstract class cannot be instantiated using the new keyword.
public abstract class MyAbstractClass {
public class perform() {
this.doStuff();
}
public abstract void doStuff();
}
How do I use an interface?
To use an interface you have your class implement it. Implementing an interface means making sure that the class specifies method bodies for all the methods in the interface. If you do not implement all the methods in the interface the compiler will make you mark the class as abstract.
public class Ford implements Car {
public void increaseSpeed() {
...
}
public void decreaseSpeed() {
...
}
public void turnRight() {
...
}
public void turnLeft() {
...
}
}
How do I use an abstract class?
An abstact class cannot be instantiated because some of the functionality (for example the doStuff() method in the example above) isn’t implemented. To use the class we need to extend it and implement any missing, abstract, methods.
public class MyClass extends MyAbstractClass {
public void doStuff() {
...
}
}
So when should I use which?
Well the real answer is it depends…
An abstract class is a good choice when you do most of the programming in the abstract class and leave only one or a couple of methods to sub-classes. An example could be a class that reads data from a file. The abstract class defines the actual reading and processing of the file and concrete sub-classes define how to get the file (from the local disk, via HTTP, via FTP etc.):
public abstract class FileProcessor {
// declarations
private File file = null;
public process() {
// get file
this.file = this.getFile();
// open file
this.openFile();
// decrypt file
this.decryptFile();
// do other stuff with the file
...
...
}
private void openFile() {
...
}
private void decryptFile() {
...
}
private abstract File getFile() throws Exception;
}
public class HttpFileProcessor extends FileProcessor {
private abstract File getFile() throws Exception {
// get file via HTTP and return it
...
}
}
public class FtpFileProcessor extends FileProcessor {
private abstract File getFile() throws Exception {
// get file via FTP and return it
...
}
}
An interface is really nice when all you need to do it define what methods are available but you want to leave the entire implementation up to the implementer. The interface in the example below only describes that a class implementing the interface knows how to process a Document object. You don’t care how the class does it but you know that you can call the process() method supplying the Document that should be processed.
public interface DocumentProcessor {
public void process(Document doc) throws Exception;
}
Another really neat thing about interfaces is that a class may implement multiple interfaces whereas it can only extend a single class. This means you can use an interface simply to signal something (for an example of this look at the java.lang.Cloneable interface in the JDK).
public class MyCar implements Car, Cloneable, Serializable {
...
}