An interface is similar to an abstract class, except that in an abstract class there can be some methods that are implemented.
However, an interface consists of all abstract methods. Because all of the methods of an interface are abstract by nature, there's no need to declare the methods as abstract. It's just a given.
The other way interfaces are different from abstract classes is that interfaces are implemented, not extended.
Any class that implements an interface must implement all of its methods, or it must declare itself as an abstract class.
Let's look at an example.
We're going to create a Product
interface and then we're going to create a Book
class that implements the product.
To create an interface, you still want to create a Java class, but when it asks what kind, you can change this to Interface.
And we can go ahead and give it a name: Product
Tip
If you forget to select that Interface, that's perfectly okay. If it creates a class, then you would just change it to interface manually.
package chapter11;
public interface Product {
}
Now inside of here, just like the abstract classes we have method definitions with no body, except we don't have to write the keyword of abstract
.
Let's go ahead and make methods for price, name, and color, since those are things that would be specific to any given product.
Product.java
package chapter11;
public interface Product {
double getPrice();
void setPrice(double price);
String getName();
void setName(String name);
String getColor();
void setColor(String color);
}
Now notice, even though we have the getter and setter methods here, we do not have the fields defined themselves.
That's because if you define a field within an interface, then that field has to be final
. Because it's final
, it's essentially a constant, and therefore you have to also give it a value.
If the purpose of the interface is so that others can inherit from this, and this is serving as just a template or a blueprint, then you don't want to add fields where the values can change based on the implementation of this interface.
So, we'll just provide the methods.
Now let's look at the Book
class.
In the Book
class, this time we're not going to use the keyword extends
— you don't inherit from an interface, you implement an interface.
To do that we use the keyword implements
and then specify the interface name.
package chapter11;
public class Book implements Product {
}
Notice we get an error already because the class must be abstract
if we're not going to implement those abstract methods.
And again, it knows that those are abstract even though we didn't explicitly say they were abstract. That is a given for interfaces.
So, I'm going to go ahead and just make some fields for this class, as well as getters and setters.
package chapter11;
public class Book implements Product {
private double price;
private String name;
private String color;
private String author;
private int pages;
private String isbn;
@Override
public double getPrice() {
return price;
}
@Override
public void setPrice(double price) {
this.price = price;
}
@Override
public String getName() {
return name;
}
@Override
public void setName(String name) {
this.name = name;
}
@Override
public String getColor() {
return color;
}
@Override
public void setColor(String color) {
this.color = color;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public int getPages() {
return pages;
}
public void setPages(int pages) {
this.pages = pages;
}
public String getIsbn() {
return isbn;
}
public void setIsbn(String isbn) {
this.isbn = isbn;
}
}
Now let's go into new class, Customer
, and we're going to use these objects.
Okay, let's make an object of type Product
called book
. Let's go ahead and attempt to instantiate this interface.
package chapter11;
public class Customer {
public static void main(String[] args){
Product book = new Product();
book.setPrice(9.99);
}
}
Notice we get an error letting us know that this cannot be instantiated.
So that's okay, we'll use our subclass and then that works just fine. If we do a dot operator on this then we see the setPrice()
method.
package chapter11;
public class Customer {
public static void main(String[] args){
Product book = new Book();
book.setPrice(9.99);
}
}
Now there's one more thing I want to show you.
I told you that all of the methods inside of an interface must be abstract, and that was true until Java version 8.
What was realized is that, let's say I created this interface that had these methods here, and then I had a bunch of subclasses out there, all types of products, books, and everything else that implemented this Product
interface.
What we have between interfaces and the classes that implement them is a contract. So, Book
, for example, is adhering to that contract by providing the implementation for all of the abstract methods. And then we could even have some other classes that use Book
and who knows what else.
If I ever wanted to change this interface and add a method, I would break everything that implemented it.
So, Java 8 introduced a new option, where I can declare methods as default
within interfaces.
If you declare the method as default
you can provide a default implementation for this method.
default String getBarcode(){
return "no barcode";
}
That way the Book
class, or any other class that implemented Product
is no longer broken.
Okay, what are the key points for interface?
Interfaces cannot be instantiated.
Interfaces are implemented, not extended.
Any class that implements an interface must implement all of its methods or it must declare itself abstract
.
Methods in an interface must be default or abstract (there's no explicit declaration needed for abstract methods)
Also notice that we didn't put an access modifier on the methods in an interface, either. That's because by default they're all public
.
While a class can only extend one class, it can implement multiple interfaces.
To implement multiple interfaces, the class header must specify a comma delimited list of names of all of the interfaces that it would like to implement.
If a class declares that it will implement multiple interfaces, then it must provide the methods specified by all of those interfaces.
Your optional exercise for this chapter is to create an abstract class called Animal
, which declares an abstract method called makeSound()
, and implements a non-abstract method called eat()
.
Then create a Pig
class and a Duck
class that both extend the Animal
class.
Finally, create a Farm
class to test these implementations.
Good luck.
Solution
Programming can be done many different ways, but here’s my solution.