When you implement an interface, you are entering into a contract, that you will implement whatever methods you have inherited. Implementing a method means that you will provide the details of the function---you will supply the function body.
At first glance, it looks like more work for the programmer because you are duplicating code. First you will write the interface but the methods doesn't have details, then you will implement in a class then supply the details of the method. This argument maybe true for trivial applications 10, but for non-trivial applications, coding against an interface rather than a concrete class is good way to use the Java typing system to achieve maintainability of code. Another reason to use interfaces is when you truly need multiple inheritance. Let us expand the Phone program.
//MultiFunction.java
import static java.lang.System.out;
interface Printer {
void print();
}
interface Phone {
void answerCall();
void dialNumber(String args);
}
interface Copier {
void copy();
}
class MultiFunction implements Printer, Phone, Copier {
public void print() {
out.println("Printing");
}
public void answerCall() {
out.println("Answering call");
}
public void dialNumber(String args) {
out.println("Dialling " + args);
}
public void copy() {
out.println("Copying");
}
}
class TestMultiFunction {
public static void main(String[] args) {
Printer printer = new MultiFunction();
Phone phone = new MultiFunction();
Copier copier = new MultiFunction();
printer.print();
phone.answerCall();
copier.copy();
System.out.println(copier.toString());
copier.print();
}
}
The Multifunction.java code defines three interfaces, the Phone, Printer and the Copier. The classMultiFunction implements all three interfaces. If you think about it, what the code is saying is---MultiFunction is a Printer, it is also a Copier and a Phone. As such, a MultiFunction object should behave as a Phone, a Printer or Copier will behave. That is the object contract between these three interfaces and the class.
If you review line 39-45 of Listing 4.8, I did not use the MultiFunction type when I created a MultiFunction object. I used the specific interfaces as the Type to be created.
Printer printer = new MultiFunction();
Phone phone = new MultiFunction();
Copier copier = new MultiFunction();
printer.print();
phone.answerCall();
copier.copy();
MultiFunction printer = new MultiFunction() would have been fine, the code will still compile and run perfectly, so why didn't I do that? Because I only need a Printer, I chose a more general type because I am not sure that I will not change the implementation details of the print() method in the future.
It can be argued that if I need to change some details of the print() function, I should just go inside the MultiFunction class and change it, but I would rather not do that for a host of reasons. The most important one being that at some point, some of my codes maybe depending on how I actually implemented the print function inside the MultiFunction class, and if I change that, some parts of the application could break. On the other hand, using the Printer interface as a type allows me to achieve loose coupling between the Type and its actual implementation. If I need to change some of the details of print() function, I could simply create another class that implements the Printer type and make that adjustments on the new class. This approach has some level of encapsulation because I am containing the possible (negative) impact of code change.
//If I need to change something on the print function()
class ColorPrinter implements Printer {
public void print() {
...
}
}
Printer printer = new ColorPrinter();
The above code shows a possible approach if I really need to make adjustments to the print() function in the future.
No comments:
Post a Comment