假设我有一个界面:
INTERFACE `IFace` (
METHOD `f` (INT) : NIL
)
我想用一个签名更广泛的方法来实现它:
CLASS `A` IMPLEMENTS `IFace` (
METHOD `f` (NUMBER n) : NIL (
PRINT n
)
)
(假设 NUMBER 是 INT 的超类型)
为什么这是不可能的?或者什么编程语言支持这个?
假设我有一个界面:
INTERFACE `IFace` (
METHOD `f` (INT) : NIL
)
我想用一个签名更广泛的方法来实现它:
CLASS `A` IMPLEMENTS `IFace` (
METHOD `f` (NUMBER n) : NIL (
PRINT n
)
)
(假设 NUMBER 是 INT 的超类型)
为什么这是不可能的?或者什么编程语言支持这个?
考虑以下示例:
第一个示例(来自您的示例):
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?
}
}
在层次结构中上升意味着超类型具有较少的功能和子类型的属性,因此接口有不被尊重的风险:如果可以抽象参数类型,那么就有可能有一个实现接口的类,将方法METHOD
f重新定义(ANY_TYPE) : NIL
为METHOD
f ,(OBJECT) : NIL
因为所有类型都继承自 Object。
因此,可以定义一个将数字传递给METHOD
f的类,(INT) : NIL
但也可以定义另一个将字符串传递给它的类,这可能会破坏接口签名和与客户端的合同(见下文)。
实现接口的主要目的是将其公开给只知道该接口的客户端,而不是实现它的类。通过这种方式,您可以将实现相同接口的不同类传递给客户端,从而在不更改客户端的情况下更改软件的功能。
与客户端的合同在接口中指定,而不是在类中(并且该合同将模拟您的高级黑盒组件设计)。
实际上,接口指定了类方法的签名(以几乎合法的方式),并且从按契约设计的角度来看,这是设计中最重要的部分。类是需要公开它的接口的化身。
因此,接口定义了类的抽象数据类型行为,如果一个类可以更改该定义,那么它可以打破与客户端更改签名的“合法”合同。
如果抽象参数,我们也在更改合同,因为更抽象的数据类型将具有更具体的不同的行为和属性。请参阅上面的示例,其中服务的提供者(类)更改了签名并因此更改了合同。合同签订后更改,没有人会高兴。
这并不限制设计,因为接口在 java 中可以具有多重继承。此外,从 JDK5 开始,您可以将泛型与接口一起使用。
所以我们可以使用泛型做以下事情:
public interface IFace<T> {
public void f(T n);
}
然后在子类中我们对类型没有限制。
请注意,在这种情况下,合同没有指定任何有关参数类型的内容,因此客户不应期待任何事情,也不能起诉我们。