Java 8 interfaces and abstract classes
Java opened up many new rules in the 1.8 implementation. One of them
is the restriction of having a declared method inside the Java interfaces. Now
in Java 1.8 you can also declare a method with a body by using the keyword “default”.
You can also have methods declared as “static”, that have a body too in the
interface. Both default and static methods in the interface are
implicitly public. If the APIs needed to add a few functionalities, then the
Java architects could have created abstract class extending those interfaces
and could have added the methods on them rather than changing the rules to
allow for the methods with body in the interfaces. These allowances also blur
some distinction between the interface and abstract class. There is
a difference between these two keywords. The default keyword can be
overridden by the implementing classes if they so please. They are referred by
the instance variables of the implementing class only. They cannot be
referenced directly through the interface. Let’s define an interface called Vehicle,
which has two default methods start( ) and stop( ), and a static
method race( ). The method drive( ) is the interface’s abstract
method.
public interface Vehicle {
public default void start(){
System.out.println("Vehicle
started !!!");
}
public default void stop() {
System.out.println("Vehicle
stopped !!!");
}
public void drive();
public static void race(){
System.out.println("Ready
to Race ? !!!");
}
}
|
Let’s look at the usage before we describe the methods further. We
override the default method start( ), and implement the abstract
method drive( ). We leave the other default method stop(
), unchanged by not overriding it.
public class Car implements Vehicle
{
@Override
public void drive() {
System.out.println("Driving
Car !!!!!");
}
@Override
public void start(){
System.out.println("Car
Started !!!");
}
public static void race() {
System.out.println("Racing
Car !!!!");
}
// print car values
public static void main(String... args) {
Car c = new Car();
c.start();
c.drive();
c.stop();
// static methods
Vehicle.race();
Car.race();
}
}
|
Looking at code above, you can notice these:
·
The default and the abstract methods are
accessed by the instance variable of the object (Car) implementing the
interface. They cannot be accessed like the class level methods.
·
The static methods can be referenced by the interface name and are similar to
static
method in classes (Vehicle.race( ) and Car.race( )), and can only be
accessed as a class level reference. There is no such thing as “overriding”
for static
methods, (this was always there in Java) as it is evident with the method race
( ).
Few reasons why the Java architects decided on allowing methods with
body are:
1.
The interfaces in use are difficult to modify.
It is impossible to add new functions without asking the implementing classes
to implement those abstract functions. It is a lot of code change for
programmers who have already coded and upgrading the java version might break
their code. All new releases must be backward compatible. The
default allows for a backdoor entry and upgrading of exiting
interfaces without breaking the existing code. Besides, most of these
interfaces have been around for decades and needed a revamp or addition.
2.
The new java additions for lambda expressions,
functional interfaces and java streams, would have required a complete new set
of classes and a huge list of abstract classes to implement them. This would
have added a lot of duplicate APIs which essentially do the same thing.
3.
The static methods in the interfaces
allow for adding utilities to the interface and its inheritors. Does this mean
that you should be using interface with static methods to create
a collection of utility methods? Absolutely not! The interfaces can be
implemented by many classes, and you might not like your utilities to be
inherited in this way. It is always prudent to write your utility methods in
class with a private constructor to prevent initialization. More details on
writing a utility class is in another section dedicated to it.
Since Java allows for multiple interface implementations you
might implement two (or more) interfaces having similar default method
declaration. How will your class decide which default method to execute when
being called? Well to prevent this the Java compiler enforces the rule that you
must explicitly override the method in your code, to resolve the conflict.
Since Java 1.8 allows default and static methods it poses a
dilemma for the new programmers on what should they use when defining a library
of classes – interfaces with static and default methods or abstract classes. The
earlier rules have not actually changed. Remember abstract classes are used to
define an abstraction of a root class (nouns). Interfaces on the other hand are
common traits (verbs or functions) that are independent of the object
hierarchy. In fact, since interfaces are now allowed default and static
methods, it takes away the need to define certain features in utility classes or
forcefully define an abstract class just to keep a set of common methods.
Comments
Post a Comment