Default Interface Methods
Java 8 added a new functionality that is very useful, default methods in interfaces.
Here's the interface for the analyzer project. This is how it's been done from the beginning of Java. The methods are declared but they have no code. Until Java 8 this is all we could do.
package java112.analyzer;
/**
* @author Alva Castillo
* class Analyzer
*/
public interface TokenAnalyzer {
void processToken(String token);
void generateOutputFile(String inputFilePath, String outputFilePath);
}
Example For Java 7
Here is an example of how it worked in Java up to Java 7. It still works this way but it's not the only way now.
First, we create an interface
and save it to its file.
A method is declared including its parameters for a full method signature.
package java112.labs2;
/**
* @author Eric Knapp
*/
public interface GreetingInterface {
String createGreeting(String person, String greeting);
}
Then we create a class that implements the interface. If we just do this we will get the compiler error that follows.
package java112.labs2;
/**
* @author Eric Knapp
* class Greetings
*/
public class Greetings implements GreetingInterface {
}
[javac] /home/student/projects/src/java112/labs2/Greetings.java:7: error: Greetings is not abstract
and does not override abstract method createGreeting(String,String)
in GreetingInterface
[javac] public class Greetings implements GreetingInterface {
[javac] ^
If we implement an interface we are promising the compiler will will have the methods listed in the interface.
Next we have to implement the method with the exact signature of the method declaration in the interface. A main
method was added so we could run the demo.
package java112.labs2;
/**
* @author Eric Knapp
* class Greetings
*/
public class Greetings implements GreetingInterface {
/**
* Create and return a greeting.
*
* @param person the person to greet
* @param greeting the message for the person
*/
public String createGreeting(String person, String greeting) {
return greeting + ", " + person + "!";
}
/**
* Run this demo.
* @param arguments The command line arguments.
*/
public static void main(String[] arguments) {
Greetings greeting = new Greetings();
System.out.println(greeting.createGreeting("Shiloh Dosela", "Hello"));
}
}
Running the demo gives us this output, as expected.
/projects$ ./runlabs2.sh Greetings
Hello, John Smith!
But, wait. What if we want the same method in more than one class? How do we avoid duplicating it? Normally the only way to do that would be through inheritance. That is not always possible in a language like Java that allows only one superclass. In Java 7 there are not many good options.
New In Java 8 - Default Methods
Now let's redo this the new way. Here's the new interface.
package java112.labs2;
/**
* @author Eric Knapp
*/
public interface GreetingInterface {
default String createGreeting(String person, String greeting) {
return greeting + ", " + person + "!";
}
}
The new keyword default
allows us to put the actual code into the interface.
And here's the class that implements the interface. Since the method is implemented in the interface itself we don't need to do it here. We can just call in the interface method.
package java112.labs2;
/**
* @author Eric Knapp
* class Greetings
*/
public class Greetings implements GreetingInterface {
/**
* Run this demo.
* @param arguments The command line arguments.
*/
public static void main(String[] arguments) {
Greetings greeting = new Greetings();
System.out.println(greeting.createGreeting("John Smith", "Hello"));
}
}
When we add the phrase implements GreetingInterface
to any class we automatically get the createGreeting
method with no other work. This is very handy.
Project 2
Here's the interface file that you should add to your java112.utilities
package.
package java112.utilities;
import java.io.*;
import java.util.*;
/**
* This interface contains a default method that can be used anywhere a Properties
* object is needed to be loaded.
* @author Eric Knapp
*
*/
public interface PropertiesLoader{
/**
* This default method will load a properties file into a Properties instance
* and return it.
* @param propertiesFilePath a path to a file on the java classpath list
* @return a populated Properties instance or an empty Properties instance if
* the file path was not found.
*/
default Properties loadProperties(String propertiesFilePath){
Properties properties = new Properties();
try {
properties.load(this.getClass().getResourceAsStream(propertiesFilePath));
} catch (IOException ioException) {
ioException.printStackTrace();
} catch (Exception exception) {
exception.printStackTrace();
}
return properties;
}
}