Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding Java Interfaces Principles

I am reading a Java book and stuck again this time thinking about what this whole paragraph actually means:

Interfaces are designed to support dynamic method resolution at run time. Normally, in order for a method to be called from one class to another, both classes need to be present at compile time so the Java compiler can check to ensure that the method signatures are compatible. This requirement by itself makes for a static and nonextensible classing environment. Inevitably in a system like this, functionality gets pushed up higher and higher in the class hierarchy so that the mechanisms will be available to more and more subclasses. Interfaces are designed to avoid this problem. They disconnect the definition of a method or set of methods from the inheritance hierarchy. Since interfaces are in a different hierarchy from classes, it is possible for classes that are unrelated in terms of the class hierarchy to implement the same interface. This is where the real power of interfaces is realized.

First question: what does the author mean by saying from one class to another? Does he mean that those classes are related in terms of the hierarchy? I mean, assigning subclass object reference to its superclass type variable and then calling a method?

Second question: what does the author again mean by saying This requirement by itself makes for a static and nonextensible classing environment? I don't understand the makes for meaning (english is not my main language) and why the environment is called static and nonextensible.

Third question: what does he mean by saying functionality gets pushed up higher and higher? Why does it get pushed up higher and higher? What functionality? Also, mechanisms will be available to more and more subclasses. What mechanisms? Methods?

Fourth question: Interfaces are designed to avoid this problem. What problem???

I know the answers must be obvious but I don't know them. Maybe mainly because I don't undestand some magic english phrases. Please help me to understand what is this whole paragraph telling.

like image 992
Salivan Avatar asked Feb 11 '23 23:02

Salivan


2 Answers

  1. Between any two classes. If your code contains a call to String.substring() for example, the String class and its substring() method must be available at compile time.
  2. As said, "makes for" means the same as "creates". The environment is non-extensible because everything you may want to use must be available at compile time. (This isn't 100% true though. Abstract classes and methods provide extension points even when no interfaces are present, but they aren't very flexible as we're going to see.)
  3. Imagine that you have two classes: Foo and Bar. Both classes extend the class Thingy. But then you want to add a new functionality, let's say you want to display both in HTML on a web page. So you add a method to both that does that.

The basic problem

  abstract class Thingy { ... }

  class Foo extends Thingy {
     ...
     public String toHTMLString() {
        ...
     }
  }

  class Bar extends Thingy {
     ...
     public String toHTMLString() {
        ...
     }
  }

This is great but how do you call this method?

 public String createWebPage( Thingy th ) {
    ...
    if (th instanceof Foo)
       return ((Foo)th).toHTMLString();
    if (th instanceof Bar)
       return ((Bar)th).toHTMLString();
    ...
 }

Clearly this way isn't flexible at all. So what can you do? Well, you can push toHTMLString() up into their common ancestor, Thingy. (And this is what the book is talking about.)

A naive attempt to resolve it

  abstract class Thingy {
     ...
     public abstract String toHTMLString();
  }

  class Foo extends Thingy {
     ...
     public String toHTMLString() {
        ...
     }
  }

  class Bar extends Thingy {
     ...
     public String toHTMLString() {
        ...
     }
  }

And then you can call it like this:

 public String createWebPage( Thingy th ) {
    ...
    return th.toHTMLString();
 }

Success! Except now you've forced every class extending Thingy to implement a toHTMLString() method, even if it doesn't make sense for some of them. Even worse, what if the two objects do not extend anything explicitly, they're completely unrelated? You'd have to push the method up all the way into their common ancestor, which is java.lang.Object. And you can't do that.

Solution with interfaces

So what can we do with interfaces?

  abstract class Thingy { ... }

  interface HTMLPrintable {
     public String toHTMLString();
  }         

  class Foo extends Thingy implements HTMLPrintable {
     ...
     public String toHTMLString() {
        ...
     }
  }

  class Bar extends Thingy implements HTMLPrintable {
     ...
     public String toHTMLString() {
        ...
     }
  }

  //We've added another class that isn't related to all of the above but is still HTMLPrintable,
  //with interfaces we can do this.
  class NotEvenAThingy implements HTMLPrintable { 
     public String toHTMLString() {
        ...
     }
  }     

And the calling code will be simply

 public String createWebPage( HTMLPrintable th ) {
    ...
    return th.toHTMLString(); // "implements HTMLPrintable" guarantees that this method exists
 }

What are interfaces then?

There are many metaphors used to understand interfaces, the most popular is probably the idea of a contract. What it says to the caller is this: "If you need X done, we'll get it done. Don't worry about how, that's not your problem." (Although the word "contract" is often used in a more general sense, so be careful.)

Or in another way: if you want to buy a newspaper, you don't care if it's sold in a supermarket, a newsagents or a small stall in the street, you just want to buy a newspaper. So NewspaperVendor in this case is an interface with one method: sellNewsPaper(). And if someone later decides to sell newspaper online or door-to-door, all they need to do is implement the interface and people will buy from them.

But my favourite example is the little sticker in shop windows that says "we accept X,Y and Z credit cards". That's the purest real-world example of an interface. The shops could sell anything (they may not even be shops, some might be restaurants), the card readers they use are different too. But you don't care about all of that, you look at the sign and you know you can pay with your card there.

like image 135
biziclop Avatar answered Feb 15 '23 09:02

biziclop


The Key to paragraph is "classes need to be present at compile time" in line 2. Classes are more concrete. While interfaces are abstract.

As classes are concrete so Designer and programmer needs to know all about class structure and how the methods are implemented. Where as interfaces are more abstract. (They contain abstract methods only). So programmer needs to know only what methods an interface has to have and signature of those methods. He does not need to know detail how these are implemented.

Thus using interfaces is easier and better while making subclasses. You only need to know method signatures of interface.

Using concrete class we have to implement functionality of a method high in class hierarchy while using interface avoids this problem. (There is a related concept of polymorphism that you would probably learn later)

like image 27
RehanZahoor Avatar answered Feb 15 '23 10:02

RehanZahoor