我对这行代码非常困惑:
public abstract class ClassName<T extends ClassName<?>>{}
我知道什么是<T>
,什么是abstract
,什么是继承,但我无法总结我在这一行中看到的所有内容。
请有人用简单的话来解释这个有趣的东西意味着什么?
与<T>
和<?>
的问题不重复。令人困惑的是ClasName
出现两次。
提前谢谢。
答案 0 :(得分:2)
所以ClassName
有一个通用参数T
,此参数需要符合某个要求,在这种情况下扩展某个类型S
,这意味着T
必须继承S
。现在有趣的是这个S
。
我们S
为ClassName<?>
,因此T
必须使用通配符从ClassName
继承。对于通配符aka问号,请查看Michael Markidis在评论中给出的链接。
现在真正有趣的是这个定义
public abstract class ClassName<T extends ClassName<?>>
允许递归泛型类型定义。所以你可以有像
这样的东西ClassName<ClassName<ClassName<ClassName<?>>>> test;
无论价值如何:)
编辑:鉴于
ClassName2<T extends ClassName<?>> extends ClassName<T>
相比之下,这相对容易。我们希望继承ClassName
但不会&#34;销毁&#34;通用参数,所以我们接受一个ClassName
会接受,在这种情况下T extends ClassName<?>
。在extends ClassName<T>
中,编译器会检查这个(ClassName2
} T
是否符合T
ClassName
的要求(请记住{ {1}}的定义)ClassName
,所以这显然有效。
此外,我们T extends ClassName<?>
延长ClassName2<?>
,所以现在您可以根据需要混合使用这两种类型:
ClassName<?>
但是,如果你愿意,请说
ClassName2<ClassName<ClassName<ClassName<?>>>> test2;
ClassName2<ClassName<ClassName2<ClassName<?>>>> test3;
(公共和抽象修饰符并不真正影响这里的通用行为),你只能拥有像
这样的东西class ClassName3<T extends ClassName3<?>> extends ClassName<T>
,因为ClassName3<ClassName3<ClassName3<ClassName3<?>>>> test4;
ClassName2<ClassName<ClassName3<ClassName3<?>>>> test5;
和ClassName
不会继承ClassName2
。
答案 1 :(得分:1)
public
表示该类对所有其他类都可见。
abstract
表示该类无法实例化(您必须为此找到一个非抽象的子类)
inheritance
是面向对象编程中的一个重要概念。阅读有关OOP的书或咨询维基百科。
T extends ClassName<?>
表示类型参数T
上有一个上限,因此T
需要是ClassName<?>
的子类。 ?
表示无限制的类型参数。
我将提供一个更有意义的示例,可以更容易理解使用有界递归类型参数的概念。让我们假设你有一个班级Thingy
。您希望Thingy
的所有子类都具有可比性,但只能属于同一个子类。也就是说,你希望指甲能够与指甲相媲美,而不是自行车:
interface Thingy<T extends Thingy<T>> extends Comparable<T> {}
class Nail implements Thingy<Nail> {
@Override public int compareTo(Nail o) { ... }
}
class Bike implements Thingy<Bike> {
@Override public int compareTo(Bike o) { ... }
}