Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/358.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 我是否可以提供使用泛型类型的方法,其中泛型类型始终是类?_Java_Generics_Subclassing - Fatal编程技术网

Java 我是否可以提供使用泛型类型的方法,其中泛型类型始终是类?

Java 我是否可以提供使用泛型类型的方法,其中泛型类型始终是类?,java,generics,subclassing,Java,Generics,Subclassing,我不确定我是否能很好地表达这个问题,我找不到更好的方法来解决这个问题,因为我对java非常陌生 如果我有课的话,我相信最好是举例说明 public abstract class Genome { abstract public Genome randomize(); abstract public Genome mutate(); abstract public Genome crossOver(Genome genome); } 我能确保它的子类总是使用泛型实现吗 p

我不确定我是否能很好地表达这个问题,我找不到更好的方法来解决这个问题,因为我对java非常陌生

如果我有课的话,我相信最好是举例说明

public abstract class Genome
{
    abstract public Genome randomize();
    abstract public Genome mutate();
    abstract public Genome crossOver(Genome genome);
}
我能确保它的子类总是使用泛型实现吗

public class GenomeSubclass extends Genome
{
    public GenomeSubclass randomize();
    // etc...
}

与合同中提供的抽象方法不同,通常的方法是这样定义:

public abstract class Genome<T extends Genome<T>> {
    abstract public T randomize();
    abstract public T mutate();
    abstract public T crossOver(T genome);
}

public class GenomeSubclass extends Genome<GenomeSubclass>
{
    public GenomeSubclass randomize();
    // etc...
}
/** verbal contract: subclass X must declare method `X crossover(X)` **/
class G

    // no explicit crossover() declaration in G

    static <X extends G> X crossover(X x1, X x2)
        X1 = x1.getClass(), X2 = x2.getClass();
        check: X2 is assignable to X1
        check: X1 has method `X1 crossover(X1)`
        invoke dynamic x1.crossover(x2)

class A

    A crossover(A)

而两者都在实施相同的基因组方法。GenomeSubclass的每个子类型都必须实现
交叉(GenomeSubclass)
方法,并且不能进一步限制参数

当然,您可以为
GenomeSubclass
提供自己的类型参数:

public class GenomeSubclass<T extends GenomeSubclass<T>> extends Genome<GenomeSubclass<T>>
{
    public GenomeSubclass<T> randomize();
    // etc...
}
然后

public class AImpl1 extends GenomeA {
   public GenomeA randomize();
   public GenomeA mutate();
   public GenomeA crossOver(GenomeA other);
}

public class AImpl2 extends GenomeA {
   public GenomeA randomize();
   public GenomeA mutate();
   public GenomeA crossOver(GenomeA other);
}

不幸的是,Java没有
This
类型,与
This
对象形成对比

通过通用技巧模拟
这个
是可以做到的,但这太糟糕了。我宁愿永远不要做这件事

现在,你为什么需要它?唯一已知的用法是方法链接。如果你有一个不同的用例,一定要告诉别人,那将是非常有趣的

如果只用于方法链,我个人不认为缺少<代码>这个< /代码>是个大问题。

编辑:交叉(此)是一个有趣的主题

假设我们有超类
G
,子类
A
B
。假设
A
只能
交叉(A)
,而
B
只能使用
B
交叉
操作是
G
上的常见操作吗

不在我们的打字系统中。当然,我们可以考虑两个代码>交叉()/<代码>,但是这种关系不能在我们的类型系统中表达。不能强制执行
X
必须声明方法
交叉(X)
的要求。(泛型也不能强制执行;想想
X扩展了G

这里有必要使用“语言外”的语言,使用另一种语言(英语)和另一种编译器(我们的眼球)来表达和加强这种关系。或者,发明一种新的静态分析器,其语法能够表达这种关系。可能需要运行时反射来执行异常的方法调度

可能是这样的:

public abstract class Genome<T extends Genome<T>> {
    abstract public T randomize();
    abstract public T mutate();
    abstract public T crossOver(T genome);
}

public class GenomeSubclass extends Genome<GenomeSubclass>
{
    public GenomeSubclass randomize();
    // etc...
}
/** verbal contract: subclass X must declare method `X crossover(X)` **/
class G

    // no explicit crossover() declaration in G

    static <X extends G> X crossover(X x1, X x2)
        X1 = x1.getClass(), X2 = x2.getClass();
        check: X2 is assignable to X1
        check: X1 has method `X1 crossover(X1)`
        invoke dynamic x1.crossover(x2)

class A

    A crossover(A)
/**口头契约:子类X必须声明方法'X交叉(X)`**/
G类
//G中没有显式的crossover()声明
静态X交叉(X x1,X x2)
X1=X1.getClass(),X2=X2.getClass();
检查:X2可分配给X1
检查:X1具有方法“X1交叉(X1)`
调用动态x1.交叉(x2)
甲级
交叉线(A)

您的帖子中没有显示任何通用代码。您显示的内容称为“协变返回”,其中子类方法重写可以返回被重写方法返回类型的子类。不确定你在问什么。他希望这些方法具有与当前扩展抽象类的类相同的返回类型。好,我想这就是他想要的。致命的:谢谢,这就是我的意思。吉姆:我没有展示,因为这正是我想要的答案。这也意味着所有不同的派生类都没有一个共同的基类。这样做不允许GenomeSubclass的派生类拥有自己的方法。我认为基因组示例已经相当不错了-比如说,你想拥有一个DNA基因组和一个RNA基因组类,这两个类都可以通过变异来创建新的DNA基因组,并与其他同类的DNA基因组和RNA基因组交叉,但不能与其他类型的DNA基因组交叉。我不知道在这类事情上,Java的范例是什么。例如,一个基因组派生类的实例可以与同一派生类的实例交叉,交叉通常需要了解从派生类调用的方法。@Paŭlo@Adam crossion确实推动了信封。在编辑中查看我的理解。
/** verbal contract: subclass X must declare method `X crossover(X)` **/
class G

    // no explicit crossover() declaration in G

    static <X extends G> X crossover(X x1, X x2)
        X1 = x1.getClass(), X2 = x2.getClass();
        check: X2 is assignable to X1
        check: X1 has method `X1 crossover(X1)`
        invoke dynamic x1.crossover(x2)

class A

    A crossover(A)