What are the new capabilities of Java interfaces? What are default methods? How can you take advantage of these capabilities?
- [Instructor] Hi, and welcome to this video on the new features of Java Interfaces. In this video we're going to see static methods in interfaces, default methods in interfaces, then we're going to consider a well-known interface called Comparator that uses these new features. Let's start with static methods. So as you probably know, interfaces in all versions of Java have always have public static final fields, so in other words, constants.
Starting from Java 8 and naturally in Java 9, they can also have public static methods. So it's the first time the interfaces can have concrete methods. Let's see an example. Consider a program that deals with graphical objects, so it may be that some of these objects can be re-sized, so they can be scaled up or down by some factor. So it may be useful to have a scalable interface so that objects that can be resized will implement this interface.
Let's check out how we can implement this scalable interface. So the first two members should not surprise you, because they could be added to any interface in all versions of Java. The first one is just a regular abstract method. It's going to be the main method of this interface, it's called setScale. It takes a scaling factor as a double, and obviously classes that implement this interface are going to implement these methods.
The second member is just a constant. It's a double constant called default_scale, initialized to 1.0, and it's implicitly public static final. Now, let's move to the new features. First of all, we can have a static concrete method in this interface. For instance, we may have a method called isScalable, which takes an arbitrary object and just returns whether this object is an instance of this interface, which could be useful to the clients.
Next, interfaces can now also have default methods. What's a default method? It's a concrete instance method, which of course can be overriden by implementing classes. So basically this is just a regular instance method characterized by the default key word, which means that interfaces used to provide just signatures of methods, they can also now provide behavior, so actual concrete instance methods.
Going back to our example, we can add a default method called resetScale, which is an instance method, a concrete instance method, which in this case just calls the abstract method setScale, with the default_scale of 1.0. With these default methods, interfaces come closer to the power of abstract classes, so let's refresh the comparison between these two language features.
The main difference is that interfaces are still stateless because they allow no instance fields, whereas abstract classes allow them. In other words, interface now provide behavior but not state, whereas abstract classes, as usual, provide both behavior and state. Which means that if you have to choose between the two, the tool you should ask yourself, whether your hierarchy contains some shared state, and if it does you should probably use abstract classes, if it doesn't you can use interfaces.
Now let's see how the comparator interface uses these new features. Before we can do that, let's introduce this simple class, which we will use in a number of examples, throughout this course. It's a simple employee class, with just two fields, called name and salary. They are a string and an integer. And there is no special methods, it's just constructor and the usual getters and setters.
Using this class, let's consider a more interesting example based on comparator. So in this main method, let's instance shade two employees called Mike and Louise with these properties. Next, let's instance shade a comparator between employees. The usual way to do that, at least before Java 8, was to use an anonymous class. We'll see later in the course a more modern way to do this with lambda expressions, but for the moment, let's stick to anonymous classes.
So this is an anonymous class which implements the compare method between two employees, by comparing the names of the two employees. Very straightforward. Let's compare using this comparator Mike and Louise. Let's actually run this example. So the first printouts are by name, and then the result of comparing Mike and Louise by name, and the result is one, because the name Mike comes after the name Louise in the alphabet.
Where does this exception come from? Well, next thing we try to do is comparing Mike with null. This is not going to work, as you can see here, because the comparator invokes b.getName, and here B is now, so there's going to be a null pointer exception. And in fact, there is, and it's printed here. Suppose we want to accept null as a parameter of our comparator and not having an exception? We can use new static method in the comparator interface.
This method is called nullslast. It accepts a comparator and returns a new comparator based on the old one, which also accepts null values and puts these null values last in the ordering. So it puts null values after all non-nulls. Therefore, we call this new comparator by name, then null. Let's use this comparator.
Let's compare Mike and Louise. Well, we still get one, as before. If we compare Mike with null, we do not get a null pointer exception anymore, we get minus one, because null, null values, go after all regular values. So Mike is smaller than null. Next, we can also find default methods in comparator, in the current version of the comparator interface, in particular one very useful such method is called reversed.
And as you can imagine, it reverses the behavior of a comparator. So we check by name then null, we reverse it, we get an ordering where null values come first and then all other values come later in the reverse order. So we call this comparator nullThenByDecreasingName. And let's use it to compare Mike and Louise. Well, we get minus one, because Mike is now smaller than Louise, because the ordering has been reversed.
Let's compare Mike and null, once again we get one, because null, null values are smaller than all other values. So Mike is bigger than null, exactly the opposite of what we used to have. That's all for this video. Let's move onto the next one on functional interfaces.
Note: To get the best results from this course, you should be familiar with basic Java programming concepts, including lists, maps, and sets, and have a suitable IDE, such as Eclipse, NetBeans, or IntelliJ.
This course was created and produced by Packt Publishing. We are honored to host this training in our library.
- What is functional programming?
- What are functional interfaces?
- Writing lambda expressions
- Creating functional interfaces
- Composing functions
- Sequential data processing with streams
- Using parallel streams