谁扩展接口?又为什么呢


20

AFAIK,我的班级extends父类和implements接口。但是我遇到了无法使用的情况implements SomeInterface。它是泛型类型的声明。例如:

public interface CallsForGrow {...}

public class GrowingArrayList <T implements CallsForGrow>  // BAD, won't work!
                              extends ArrayList<T> 

implements语法上禁止使用。我首先想到的是,完全禁止在<>中使用接口,但是没有。有可能,我只需要使用 extends而不是implements。结果,我正在“扩展”接口。这个另一个例子有效:

public interface CallsForGrow {...}

public class GrowingArrayList <T extends CallsForGrow>  // this works!
                              extends ArrayList<T> 

在我看来,这似乎是句法上的不一致。但是也许我不理解Java 6的一些技巧?我应该在其他地方扩展接口吗?我要扩展的接口是否应该具有某些特殊功能?

Answers:


25

对于泛型类型变量,编译器实际上并不关心T是类,接口,枚举还是注释。它关心的只是它是具有给定的子类型和超类型集合的类型。

并且没有理由仅仅因为在另一个地方(实际上是在实现接口的地方)而使语法复杂化(例如,如果您使用implement一个接口,则需要实现它定义的所有方法,但是如果您extend是(非抽象的)课程,则不需要。

假设您需要在implements此处写一会儿,那么您还需要为enum值(而不是简单地编写<E extends Enum<E>>)和注释(可以使用轻松声明)使用单独的语法<A extends Annotation>

您唯一需要编写implements的地方就是实际实现接口的地方。在一点上(仅在一点上),区别很重要,因为您必须实现接口中定义的方法。对于其他所有人,给定的A是基类还是已实现的接口都没关系B:这是一个超类型,这很重要。

还要注意,还有其他地方可以使用extends接口:

interface A {
}

interface B extends A {
}

此时implements将是错误的,因为B 未实现 A


如果我们使用您的逻辑,则应始终使用“ extends SomeInterface” ,而不仅限于泛型。
Gangnus

2
@Gangnus:不,因为对于实现者extendsand 之间有具体的区别implements,只是从纯类型系统的角度看问题时,没有区别。
约阿希姆·绍尔

1
抱歉,我不明白您的想法。--1。为什么在一种情况下而不是在另一种情况下使用“纯类型系统视角”?--2。为什么语法要求在这些不同的地方发生变化?请您解释一下。如果可能,在答案中。
Gangnus 2012年

1
@Gangnus:谁说那T是一堂课?T可以引用接口类型或enum类型。
约阿希姆·绍尔

1
来自C#,整个讨论很荒谬。我们用表示类型的超类型:。在幕后,接口一直是并且一直是抽象类,并且仅包含未实现的virtual(abstract)成员,以允许多重继承。implements和之间没有任何区别extends。它们都可以用相同的单词(extends)或某个任意符号(:)代替,并且不会丢失任何内容。
萨拉

5

当最初向感兴趣的开发人员提供Java 5(尤其是泛型)时,其语法就完全不同了。而不是Set<? extends Foo>Set<? super Bar>它具有Set<+Foo>Set<-Foo>。但是,反馈是不清楚是+更具体还是更广泛(更多类)。Sun通过更改语法来响应该反馈,但是在不引入新关键字的限制内,这可能是向后兼容的问题。

结果是两者都不是很自然的。如您所见,extends谈论类“扩展”接口是很重的,它不是在其他上下文中使用的语言。并且super重载为“是”的超类,这是先前由关键字表示的关系的相反方向,即引用超类。

但是,接口的基本原理不受此更改的影响,并且不会引入以新方式扩展的特殊接口。


+1。我明白并同意。但是Joachim Sauer发现我错误地认为T必然是一类。因此,答案是他的。您的理解是一层(或2层):-)。我的问题比较原始。无论如何,谢谢您的发展。
Gangnus

2

有两个允许和禁止这样的语法,而这些缺点使得有更大。

试想一下。

接口与实现的分离是基本的编程习惯用法之一。因此,允许拼写“接口实现某些东西”的语法与使用加号表示操作数乘法的语法差不多。


好。所以,我真的不明白。我认为这很有可能。但是对不起,您根本没有解释问题。T是类的表示。为什么在一个地方我使用T扩展而在另一个地方T实施?
Gangnus

在您提供的示例中,@ Gangnus表示类型参数,它不一定是类,请参阅Joachim告诉您的内容。允许使用工具会导致我提到的同样的混乱
gnat'2

是的,我已经看过他的评论。输入答案后,它将被标记为答案。直到你们俩都感谢我并+1。
Gangnus

-1

在理解接口的同时,下一步需要理解接口驱动的编程。它告诉接口的实际用途。它在Java(或任何其他语言)程序中扮演什么角色。


2
您的答案如何解决OP的担忧?请修改您的答案以使其更清晰。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.