我想知道Java中是否有特殊原因总是使用“ extends
”而不是“ implements
”来定义类型参数的界限。
例:
public interface C {}
public class A<B implements C>{}
被禁止,但
public class A<B extends C>{}
是正确的。是什么原因呢?
implements
不带来新的东西并使事情变得更加复杂。希望对您有帮助。
我想知道Java中是否有特殊原因总是使用“ extends
”而不是“ implements
”来定义类型参数的界限。
例:
public interface C {}
public class A<B implements C>{}
被禁止,但
public class A<B extends C>{}
是正确的。是什么原因呢?
implements
不带来新的东西并使事情变得更加复杂。希望对您有帮助。
Answers:
在类“实现”还是“扩展”之间,通用约束语言没有语义差异。约束可能性是“扩展”和“超”-也就是说,该类是可分配给其他类的对象(扩展),还是该类可从该类分配(超级)。
class Generic<RenderableT extends Renderable implements Draggable, Droppable, ...> { Generic(RenderableT toDrag) { x = (Draggable)toDrag; } }
有人要进行编译时检查。
答案在这里 :
要声明有界的类型参数,请列出类型参数的名称,后跟
extends
关键字,然后是其上限 […]。注意,在这种情况下,extends在一般意义上用于表示extends
(如在类中)或implements
(如在接口中)。
因此,有了它,这有点令人困惑,Oracle知道了。
getFoo(List<? super Foo> fooList)
只能使用Foo like扩展了字面的类class Foo extends WildcardClass
。在这种情况下,a List<WildcardClass>
是可接受的输入。但是,任何Foo
实现的类均无法正常工作class Foo implements NonWorkingWildcardClass
并不意味着List<NonWorkingWildcardClass>
会在中有效getFoo(List<? super Foo> fooList)
。晶莹剔透!
可能是因为对于双方(B和C),仅类型是相关的,而不是实现。在你的例子中
public class A<B extends C>{}
B也可以是接口。“扩展”用于定义子接口以及子类。
interface IntfSub extends IntfSuper {}
class ClzSub extends ClzSuper {}
我通常认为“ Sub扩展Super”是“ Sub就像Super一样,但是具有附加功能”,而“ Clz实现Intf”是“ Clz是Intf的实现”。在您的示例中,这将匹配:B类似于C,但是具有附加功能。功能在这里是相关的,而不是实现。
我们习惯了
class ClassTypeA implements InterfaceTypeA {}
class ClassTypeB extends ClassTypeA {}
与这些规则的任何细微差异都会使我们感到困惑。
类型绑定的语法定义为
TypeBound:
extends TypeVariable
extends ClassOrInterfaceType {AdditionalBound}
如果我们要更改它,我们肯定会添加implements
大小写
TypeBound:
extends TypeVariable
extends ClassType {AdditionalBound}
implements InterfaceType {AdditionalBound}
并以两个相同处理的子句结束
ClassOrInterfaceType:
ClassType
InterfaceType
(JLS 12> 4.3。引用类型和值>ClassOrInterfaceType
)
除了我们还需要注意implements
,这会使事情进一步复杂化。
我相信这是为什么主要原因extends ClassOrInterfaceType
是代替extends ClassType
和implements InterfaceType
-让事情变得简单了复杂的概念之内。问题在于我们没有一个合适的词来覆盖这两个词extends
,implements
而且我们绝对不想引入一个词。
<T is ClassTypeA>
<T is InterfaceTypeA>
尽管extends
在与接口一起使用时会带来一些混乱,但是它是一个广义的术语,可以用来描述这两种情况。尝试将您的思想调整为扩展类型的概念(不扩展类,不实现接口)。您可以通过另一种类型来限制类型参数,而该类型实际上是什么并不重要。唯一重要的是它是它的上限和它的超类型。
实际上,当在接口上使用通用时,关键字也为extends。这是代码示例:
有2个类实现了Greeting接口:
interface Greeting {
void sayHello();
}
class Dog implements Greeting {
@Override
public void sayHello() {
System.out.println("Greeting from Dog: Hello ");
}
}
class Cat implements Greeting {
@Override
public void sayHello() {
System.out.println("Greeting from Cat: Hello ");
}
}
和测试代码:
@Test
public void testGeneric() {
Collection<? extends Greeting> animals;
List<Dog> dogs = Arrays.asList(new Dog(), new Dog(), new Dog());
List<Cat> cats = Arrays.asList(new Cat(), new Cat(), new Cat());
animals = dogs;
for(Greeting g: animals) g.sayHello();
animals = cats;
for(Greeting g: animals) g.sayHello();
}
implements
?” -“因为只有extends
”。