Question

Let's say I have an interface:

INTERFACE `IFace` (
  METHOD `f` (INT) : NIL
)

And I would like to implement it with a method that has a wider signature:

CLASS `A` IMPLEMENTS `IFace` (
  METHOD `f` (NUMBER n) : NIL (
    PRINT n
  )
)

(Suppose that NUMBER is a supertype of INT)

Why is this not possible? Or what programming languages support this?

Was it helpful?

Solution

Short answer:

Consider the following examples:

First Example (from your example) :

INTERFACE `IFace` (
  METHOD `printFibonacci` (INT) : NIL
)

CLASS `A` IMPLEMENTS `IFace` (
  METHOD `printFibonacci` (NUMBER n) : NIL (
    //what if the number is a not an integer? Can we guarantee to the client that we are respecting the method signature?
  )
)

Second Example:

public interface Talking {

    public void speak(Human human);

}


public class Employee implements Talking {

    public void speak(Animal animal) {
        // can we speak with a cockroach?
    }
}

Going up in the hierarchy means that the supertype has less functions and attributes of the subtype so the interface risks to be NOT respected: if it was be possible to abstract a param type, then it will be ever possible to have a class implementing an interface, redefining the method METHODf(ANY_TYPE) : NIL to METHODf(OBJECT) : NIL because all types inherit from Object.

And so it would be possible to define a class that pass a number to METHODf(INT) : NIL but also to define another class that pass a string to it, risking to break the interface signature and the contract with the client (see below).

Long answer:

The main purpose of implementing an interface is to expose it to a client which will know only that interface, not the classes implementing it. In this way you can pass to the client different classes implementing the same interface, changing the features of the software without changing the client.

The contract with the client is specified in the interface NOT in the class (and that contract is going to model your high level, black box component design).

Indeed the interface specify the signature (in almost a legal way) of the class method, and from a Design By Contract point of view that is the most important part of the design. Classes are incarnation of interfaces which needs to expose it.

So the interface is defining the Abstract Data Type behavior of a class and if a class can change that definition then it can break the "legal" contract with the client changing the signature.

And we are changing the contract also if abstracting params, because more abstract data types will have different behavior and attributes of more concrete ones. See example above in which the provider of the service (the class) change the signature and therefore the contract. No one is happy when a contract is changed after it has been signed.

This is not limiting the design because interfaces can have multiple inheritance in java. Moreover from JDK5 you can use Generics with interfaces.

So we can do the following using Generics:

public interface IFace<T> {
    public void f(T n); 
}

and then in the subclasses we have no constraint on the type.

Note that in this case the contract is not specifying anything about the parameters type, so the client should not expect anything and cannot sue us.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top