Java &引用;A类<;T扩展了SomeClass<;T>&燃气轮机&引用;工作方式与B类不同<;T扩展了一些接口<;T>>?(是的)

Java &引用;A类<;T扩展了SomeClass<;T>&燃气轮机&引用;工作方式与B类不同<;T扩展了一些接口<;T>>?(是的),java,generics,Java,Generics,而涉及接口的定义具有可比性 class B <T extends Comparable<T>> B类 是众所周知且可实例化的,在扩展类而不是接口时,相同的用法不会以相同的方式工作。这里有一个例子 class G <T extends Box<T>> { T val; G(T val) { this.val = val; } } class RussianBoxContainer2 <T exten

而涉及接口的定义具有可比性

class B <T extends Comparable<T>>
B类
是众所周知且可实例化的,在扩展类而不是接口时,相同的用法不会以相同的方式工作。这里有一个例子

class G <T extends Box<T>> {
    T val;
    G(T val) {
        this.val = val;
    }
}
class RussianBoxContainer2 <T extends RussianBoxContainer2<T>>   {
    RussianBoxContainer2<T> value; 
    RussianBoxContainer2(RussianBoxContainer2<T> box) {
        this.value = box;
    }
    public String toString() {
        return this.getClass().getSimpleName()+" containing {"+this.value+"}";
    }
}
G类{
T值;
G(T val){
this.val=val;
}
}
上面的类是编译的,但我找不到一种实例化的方法。它似乎需要一个无限嵌套的Box

G<Box<Box<..>>>
G
下面是我对类框的定义

class Box <T> {
    T val;
    Box(T val) {
        this.val = val;
    }
}
类框{
T值;
盒子(T val){
this.val=val;
}
}
为了便于讨论,这里有几个类似的例子。我测试了我所有的代码

下面这节课的意思我很清楚

class D <T extends Box<String>> {
    T val;
    D(T val) {
        this.val = val;
    }
}
D类{
T值;
D(T val){
this.val=val;
}
}
我们可以使用

    D<Box<String>> d = new D<>( new Box<String> ("hello") );
    F<String,Box<String>> f = new F<>( new Box<String> ("hello") );
dd=newd(新框(“hello”);
我们可以对其进行推广,使该框可以包含任何内容

class F <S, T extends Box<S>> {
    T val;
    F(T val) {
        this.val = val;
    }
}
F类{
T值;
F(T val){
this.val=val;
}
}
我们可以使用

    D<Box<String>> d = new D<>( new Box<String> ("hello") );
    F<String,Box<String>> f = new F<>( new Box<String> ("hello") );
F=new F(新框(“hello”);
回到最初的问题,以下内容是什么意思,如何/可以实例化

class G <T extends Box<T>> {
    T val;
    G(T val) {
        this.val = val;
    }
}
G类{
T值;
G(T val){
this.val=val;
}
}

这个类G是我第一次尝试泛化上面的类D,这样Box就可以容纳任何类型,而不仅仅是字符串。后来我提出了类F作为问题的解决方案,但我想知道G是什么意思,为什么它与
T扩展SomeInterface

不同,如果
Box
类没有
T
的构造函数,那么您可以创建一个扩展
Box
的类。例如:

class NewBox extends Box<NewBox> {
    ...
}
但是在您的案例中,Box有构造函数
Box(T val){…}
,然后
NewBox
需要匹配
super
的构造函数,比如:

class NewBox extends Box<NewBox> {
    NewBox(NewBox val) {
        super(val);
    }
}

如果您关心类型绑定
T extends Box
,则表示可以指定为类型参数的唯一类型必须扩展
Box

此技术用于指定可以对您的类型执行的其他操作(例如,众所周知的
Comparable
),因此使用类而不是接口并不是很常见

让我给你举个例子。假设我们有以下操作

interface Op1<T>{
    void doOp1(t: T): T
}

interface Op2<T> {
   void doOp2(t: T): T
}

class MyClass implements Op1<MyClass>, Op2<MyClass>{
    //By implementing Op1 and Op2 you
    //specify that operations doOp1 and doOp2
    // can be applied to variable of typr MyClass
}
在函数式编程中,类似(但并非完全相同)的东西称为类型类 根据对
@Ruslan
@Some Name
的回答以及对该问题的评论,这里简要介绍了两者之间的区别

class G <T extends SomeClass<T>>
class B <T extends SomeInterface<T>>  
class Enum<E extends Enum<E>>   
下面是一个类似
T

class RussianBox extends Box<RussianBox> {
    RussianBox(RussianBox box) {
        super(box);
    }
}
class Integer extends Number implements Comparable<Integer>
下面是一个类的示例,如
G

class RussianBoxContainer <T extends Box<T>>   {
    T value; 
    RussianBoxContainer(T value) {
        this.value = value;
    }
    public String toString() {
        return this.getClass().getSimpleName()+" containing {"+this.value+"}";
    }
}
2. <代码>B类 类
B
要求类型
T
定义如下

class T extends SomeClass<T> {}
class T extends SomeClass implements SomeInterface<T> {}
因此,当引用接口而不是类时,此模式的行为非常不同

3. <代码>类枚举 现在创建一个类,如
Enum
。这里有一个例子

class G <T extends Box<T>> {
    T val;
    G(T val) {
        this.val = val;
    }
}
class RussianBoxContainer2 <T extends RussianBoxContainer2<T>>   {
    RussianBoxContainer2<T> value; 
    RussianBoxContainer2(RussianBoxContainer2<T> box) {
        this.value = box;
    }
    public String toString() {
        return this.getClass().getSimpleName()+" containing {"+this.value+"}";
    }
}
下面的代码实例化了这两个类

RussianBox2 russianBox2 = new RussianBox2(new RussianBox2(null));
out.println("russianBox2 = " + russianBox2 );

RussianBoxContainer2<RussianBox2> containerForARussianBox2 = new RussianBoxContainer2<>(russianBox2);
out.println("containerForARussianBox2 = " + containerForARussianBox2 );

如果
T
Box
的子类,这意味着
Box
必须在
T
之前存在,这从直觉上看似乎是不可能的(即使
T
只是任何类的占位符)。你在什么地方见过这个或者这是假设的吗?@Gendarme这只是一个假设的问题。实际上,它看起来像(至少当
a
是一个接口时)。对于类来说也是可能的。事实上,后面的泛化
类F
并没有真正意义。如果您引入了某种类型绑定,例如
class F
,则会出现这种情况。这将允许您在
S
上使用抽象比较。但这并没有回答我最初的问题,即如何实例化G,其中Box是一个类,以及Box是一个类时意味着什么。@RFS您不能使用
Box
本身实例化
G
。正如你所注意到的,这需要无限的需求。您需要将其子类化为
Mcls-extends-Box
(例如
Integet-implements-compariable
)@RFS,以了解
Box
是一个类时的含义。我无法想象任何常见的用例。您最好描述一下您使用该类的意图。当它是一个类时,它禁止使用组合类型绑定,例如
类Tox{}
。您不能添加额外的绑定,因为不可能添加
类别G
。当它是一个
接口时,正如我所说,它意味着在类型
T
上的一个附加操作:
类G
@RFS更新了一个示例地址原始问题
@Ruslan
,我尝试了它。按预期工作。谢谢
class Integer extends Number implements Comparable<Integer>
class RussianBoxContainer2 <T extends RussianBoxContainer2<T>>   {
    RussianBoxContainer2<T> value; 
    RussianBoxContainer2(RussianBoxContainer2<T> box) {
        this.value = box;
    }
    public String toString() {
        return this.getClass().getSimpleName()+" containing {"+this.value+"}";
    }
}
class RussianBox2 extends RussianBoxContainer2<RussianBox2> {
    RussianBox2(RussianBox2 box) {
        super(box);
    }
}
RussianBox2 russianBox2 = new RussianBox2(new RussianBox2(null));
out.println("russianBox2 = " + russianBox2 );

RussianBoxContainer2<RussianBox2> containerForARussianBox2 = new RussianBoxContainer2<>(russianBox2);
out.println("containerForARussianBox2 = " + containerForARussianBox2 );
russianBox2 = RussianBox2 containing {RussianBox2 containing {null}}
containerForARussianBox2 = RussianBoxContainer2 containing {RussianBox2 containing {RussianBox2 containing {null}}}