Java 我是否可以提供使用泛型类型的方法,其中泛型类型始终是类?
我不确定我是否能很好地表达这个问题,我找不到更好的方法来解决这个问题,因为我对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
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)