2

假设我有一个界面:

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

我想用一个签名更广泛的方法来实现它:

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

(假设 NUMBER 是 INT 的超类型)

为什么这是不可能的?或者什么编程语言支持这个?

4

1 回答 1

2

简短的回答:

考虑以下示例:

第一个示例(来自您的示例):

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?
  )
)

第二个例子

public interface Talking {

    public void speak(Human human);

}


public class Employee implements Talking {

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

在层次结构中上升意味着超类型具有较少的功能和子类型的属性,因此接口有不被尊重的风险:如果可以抽象参数类型,那么就有可能有一个实现接口的类,将方法METHODf重新定义(ANY_TYPE) : NILMETHODf ,(OBJECT) : NIL因为所有类型都继承自 Object。

因此,可以定义一个将数字传递给METHODf的类,(INT) : NIL但也可以定义另一个将字符串传递给它的类,这可能会破坏接口签名和与客户端的合同(见下文)。

长答案:

实现接口的主要目的是将其公开给只知道该接口的客户端,而不是实现它的类。通过这种方式,您可以将实现相同接口的不同类传递给客户端,从而在不更改客户端的情况下更改软件的功能。

与客户端的合同在接口中指定,而不是在类中(并且该合同将模拟您的高级黑盒组件设计)。

实际上,接口指定了类方法的签名(以几乎合法的方式),并且从按契约设计的角度来看,这是设计中最重要的部分。类是需要公开它的接口的化身。

因此,接口定义了类的抽象数据类型行为,如果一个类可以更改该定义,那么它可以打破与客户端更改签名的“合法”合同。

如果抽象参数,我们也在更改合同,因为更抽象的数据类型将具有更具体的不同的行为和属性。请参阅上面的示例,其中服务的提供者(类)更改了签名并因此更改了合同。合同签订后更改,没有人会高兴。

这并不限制设计,因为接口在 java 中可以具有多重继承。此外,从 JDK5 开始,您可以将泛型与接口一起使用。

所以我们可以使用泛型做以下事情:

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

然后在子类中我们对类型没有限制。

请注意,在这种情况下,合同没有指定任何有关参数类型的内容,因此客户不应期待任何事情,也不能起诉我们。

于 2012-11-12T04:31:05.997 回答