Java Interfaces Explained – 040


One advance I’m really hoping for in the future
is driverless cars. I really hate driving, unless it’s at ludicrous speed! That’s just
fun. My requirements for the driverless car are very simple. I need it to accept a location,
drive me to the destination, and wake me when it gets there. I really don’t care what company
does it first or how it gets done. The car just has to be capable of performing my three
tasks. You can think of these car tasks as a contract
of three methods for a class. Set location, drive, and wake me up. That’s what an interface
is. It’s a contract that states any class implementing this interface can be typed as
the interface and it guarantees the methods listed in the interface will be implemented.
So let’s talk about how interfaces work, and how we can use them in our applications. When defining an interface, we use the keyword
“interface” instead of class. That’s pretty much the biggest difference. Interfaces must
be public or package scope. If we don’t specify the scope of the interface, it’s protected. We can have attributes in an interface, but
the catch is all attributes must be public, static and final. That’s a constant. Even
if we don’t declare the attribute scope, Java makes the attribute public, static and final.
The reason is interfaces are contracts, they can’t hold state. If we need state, we should
use classes. Sometimes we’ll see a constant interface pattern.
The idea is we put a ton of constants in an interface, and we add the interface where
we need it. It’s a bad idea, and it’s considered an anti-pattern. If you ever find yourself
wanting to create a constant interface, put the constants in a final class. For the most part, interfaces are only method
declarations, and we do not implement any of the methods. We’ll cover the exception
later. When we talk about interfaces, we’re not talking
about the is-a relationship we see with inheritance. We say the class implements or does x. We
use the keyword “implements” on our class. If we use the interface as a type, it points
to a class instance that implements the interface. We cannot create an instance of an interface.
Sometimes we see interfaces used to describe an “is-a” relationship as well. It’s usually
when the interface is used as the type for the class. I prefer to use the words “does”,
“acts like”, or “implements” when describing the relationship between interface concepts. We can create a hierarchy of interfaces. In
this case, we’re extending the contract of methods with more methods. In this case, we’ll
use the keyword “extends”. In Java we usually add the word “-able” after
the name. So if the interface’s purpose is to be self driving, we might name the interface
SelfDriveable. It’s a weird convention, and you’ll see some very strange mental gymnastics
to create an interface name that can end in “-able”. My recommendation is to try your
best, but if the interface name would be clearer with out the “-able” suffix you can skip it.
The other option is to prefix the interface with the word “Can”, as in CanSelfDrive. Recently the people at Java ran into a situation
where they were painted into a corner. Most of their collection classes are defined using
interfaces. They wanted to add functional programming to their interfaces, but if they
changed the interface it would break every class using the interface. The interfaces
are a fundamental part of Java, so it would break other people’s code. To solve this problem, they added something
called default or defender methods to interfaces. Defender methods enable us to add new functionality
to interfaces and ensure binary compatibility with code written for older versions of those
interfaces. This means we can provide default functionality
for some methods. To do this, we use the keyword “default” when defining the method, and provide
the default implementation of the method. Defender methods can lead to a situation where
two interfaces provide a defender method with the same name. In this case, the code will
not compile and we cannot use the two interfaces together. When we have an interface that extends another
interface, we can call any super interface defender method. We do this using the interface
name with the super keyword. Sometimes you’ll see an interface containing
no methods at all. It’s just an empty interface. These are called marker interfaces. They inform
the compiler the objects of the classes implementing the marker interface need to be treated differently. An example of this in Java is the Serializable
interface. Serializable says this object can be copied, stored to disk, and then recreated.
There are conventions, but there are no methods we are forced to implement. Java won’t let
you serialize an object unless you tell the compiler it’s ok. The marker interface does
that by checking for the interface type. There’s one other type of interface. It’s
called a functional interface. This is an interface containing exactly one method. It’s
also marked with something called an annotation. The annotation isn’t required. The annotation
lets the compiler know it should enforce single abstract method inside the interface. These
interfaces are important for functional programming and lambdas. We’ll cover those later, but
you should be aware of what is a functional interface. The first thing that might come to mind is,
how are these different from abstract classes? An abstract class is a partially completed
class. It’s up to us to complete the class when we derive from it. Since it’s a class,
you can only inherit from a single class. If we want to add or change behavior, abstract
classes force us to use inheritance. Interfaces say we promise to implement the
methods listed in the interface, but there’s no limit to the number of interfaces our class
will implement. Our classes are free to use as many interfaces as needed. That’s why I
say “does” is a better relationship word for interfaces. A class usually represents one
concept, but it can “do” many actions. The most common use for interfaces is to hide
the details of a class. If we look at the List interface in Java, it contains many methods
for manipulating a list. Behind the interface curtain, there are many types of lists. There’s
an ArrayList, a LinkedList, a Vector and so on. With the list interface, we’re separating
what each class does from how it does it. The actual class used doesn’t matter. If we need to change the class behind the
scenes, say a different class handles large lists better than the one we’re using, we
can swap the class without needing to change much code. This is called programming to an
interface. In most cases, we want to avoid inheritance.
We should use abstract classes only when we want to include functionality, but parts of
the class’s purpose need to be implemented by the child class. With abstract classes,
you are forcing other developers to implement child classes using inheritance. Interfaces
are much easier to add to existing classes, and with defender methods there is little
reason to not consider interfaces first. OK, that was another very long tutorial. Thank
you for making it to the end! If you have any questions let me know in the
comments. Liking the video helps me understand what I’m doing right, so if you liked the
video… you know what to do. And with that, I’ll see you in the next
video!

Leave a Reply

Your email address will not be published. Required fields are marked *