在抽象方法中声明的动态 return 类型的实现
Dynamic return type of implementation declared in abstract method
我正在寻找一种方法,在抽象方法中使 return 类型成为调用该方法的实现之一。
换句话说,我想写这样的东西:
public class GenericClass {
public <T extends GenericClass> T returnMyself() {
return (T)this; // Compiler warning, unsafe cast
}
}
public class Implem1 extends GenericClass {}
public class Implem2 extends GenericClass {}
public class Main {
public static void main(String[] args) {
Implem1 implem1 = new Implem1();
Implem1 again1 = implem1.returnMyself(); // Works fine, the type is inferred by the type of again1, I think
Implem1 again2 = implem1.<Implem1>returnMyself(); // Works fine, the type is explicitly asked by <Implem1>
Implem2 again3 = implem1.returnMyself(); // Works fine while it shouldn't.
}
}
我正在寻找的是一种声明方法的方法,以便在编译时,returnMyself() 只能 return 调用它的实现类型(在我的示例中, implem1 是 Implem1 类型),并确保调用的代码不能 mistake/mix 类型。
我搜索了很多但找不到我的答案(有些主题看起来相似但想要更一般的情况,而不是明确调用该方法的实现类型)。
一些答案是正确的,但总是暗示要覆盖每个实现中的方法 class,这对我来说可能很麻烦且容易出错。理想情况下,我正在寻找一种只需要在摘要 class.
中编写一次的方法
任何 help/answer 赞赏 :D
既然您想在子类中编写这些方法,这似乎是可行的。您可以覆盖方法并使用不同的 return 类型,只要新的 return 类型是旧类型的扩展:
Can overridden methods differ in return type?
你可以这样做:
public class Parent {
public Parent returnMyself() {
return this;
}
}
public class Child extends Parent {
public Child returnMyself() {
return this;
}
}
这没问题,因为如果您将 Child
实例存储在 Parent
变量中,那么您期望 Parent
return 类型的 returnMyself()
。即使它实际上是一个 Child
对象,由 returnMyself()
编辑的 Child
return 扩展了 Parent
所以你去吧。
既然你在问题描述中提到了抽象,那么遵循类似于 Java 的 Enum class 的模型如何,其中通用类型在 class 定义?
public abstract class GenericClass<T extends GenericClass> {
public abstract T returnMyself();
}
public class Implem1 extends GenericClass<Implem1> {
@Override
public Implem1 returnMyself() {
return this;
}
}
public class Implem2 extends GenericClass<Implem2> {
@Override
public Implem2 returnMyself() {
return this;
}
}
public class Main {
public static void main(String[] args) {
Implem1 implem1 = new Implem1();
Implem1 again1 = implem1.returnMyself(); // Works fine
Implem1 again2 = implem1.returnMyself(); // Works fine
Implem2 again3 = implem1.returnMyself(); // Does not compile
}
}
我正在寻找一种方法,在抽象方法中使 return 类型成为调用该方法的实现之一。
换句话说,我想写这样的东西:
public class GenericClass {
public <T extends GenericClass> T returnMyself() {
return (T)this; // Compiler warning, unsafe cast
}
}
public class Implem1 extends GenericClass {}
public class Implem2 extends GenericClass {}
public class Main {
public static void main(String[] args) {
Implem1 implem1 = new Implem1();
Implem1 again1 = implem1.returnMyself(); // Works fine, the type is inferred by the type of again1, I think
Implem1 again2 = implem1.<Implem1>returnMyself(); // Works fine, the type is explicitly asked by <Implem1>
Implem2 again3 = implem1.returnMyself(); // Works fine while it shouldn't.
}
}
我正在寻找的是一种声明方法的方法,以便在编译时,returnMyself() 只能 return 调用它的实现类型(在我的示例中, implem1 是 Implem1 类型),并确保调用的代码不能 mistake/mix 类型。
我搜索了很多但找不到我的答案(有些主题看起来相似但想要更一般的情况,而不是明确调用该方法的实现类型)。
一些答案是正确的,但总是暗示要覆盖每个实现中的方法 class,这对我来说可能很麻烦且容易出错。理想情况下,我正在寻找一种只需要在摘要 class.
中编写一次的方法任何 help/answer 赞赏 :D
既然您想在子类中编写这些方法,这似乎是可行的。您可以覆盖方法并使用不同的 return 类型,只要新的 return 类型是旧类型的扩展:
Can overridden methods differ in return type?
你可以这样做:
public class Parent {
public Parent returnMyself() {
return this;
}
}
public class Child extends Parent {
public Child returnMyself() {
return this;
}
}
这没问题,因为如果您将 Child
实例存储在 Parent
变量中,那么您期望 Parent
return 类型的 returnMyself()
。即使它实际上是一个 Child
对象,由 returnMyself()
编辑的 Child
return 扩展了 Parent
所以你去吧。
既然你在问题描述中提到了抽象,那么遵循类似于 Java 的 Enum class 的模型如何,其中通用类型在 class 定义?
public abstract class GenericClass<T extends GenericClass> {
public abstract T returnMyself();
}
public class Implem1 extends GenericClass<Implem1> {
@Override
public Implem1 returnMyself() {
return this;
}
}
public class Implem2 extends GenericClass<Implem2> {
@Override
public Implem2 returnMyself() {
return this;
}
}
public class Main {
public static void main(String[] args) {
Implem1 implem1 = new Implem1();
Implem1 again1 = implem1.returnMyself(); // Works fine
Implem1 again2 = implem1.returnMyself(); // Works fine
Implem2 again3 = implem1.returnMyself(); // Does not compile
}
}