我觉得这是不可能的,但如果没有,那将是非常有用的。
我正在尝试以子类只有新方法,没有新构造函数,没有新字段的方式扩展父类。因此子类的基础数据结构与父类相同。当我想为内置的java类(例如Vector3d
)提供附加函数时,就会发生这种情况。鉴于底层数据是相同的,可以以任何方式将初始化为父类的对象向下转换为子类,以便我可以使用添加的功能。作为我的意思的一个例子,见下文
import javax.vecmath.Vector3d;
public class Vector3dPlus extends Vector3d{
//same fields, same constructors as Vector3d
public double extraMethod(){
return x+y+z;
}
}
尝试使用添加到Vector3d的新方法
import javax.vecmath.Vector3d;
public class Test {
public static void main(String[] args) {
Vector3d basic=new Vector3d(1,2,3);
useExtraMethod(basic); //this line correctly raises an exception, but is there a way around that
}
public static void useExtraMethod(Vector3dPlus plus){
System.out.println(plus.extraMethod());
}
}
显然,java对此感到不安,因为通常我们无法保证Vector3dPlus
方法适用于所有Vector3d
。但无论如何,我可以向java说底层数据结构是相同的,因此允许从Vector3d
到Vector3dPlus
的所有向下转换。
我处理这个问题的当前方法是将所有额外的方法放在一个通用的实用程序类中,但这显然有点可怕
答案 0 :(得分:4)
您可以使用方法重载和复制构造函数来实现它:
public class Vector3dPlus extends Vector3d {
public Vector3dPlus(Vector3d vector) {
super( ... ); // parameters from vector
}
// rest of your Vector3dPlus code
}
并在您的测试类中重载方法:
public class Test {
public static void useExtraMethod(Vector3d vector) {
useExtraMethod(new Vector3dPlus(vector));
}
public static void useExtraMethod(Vector3dPlus plus){
System.out.println(plus.extraMethod());
}
public static void main(String[] args) {
Vector3d basic=new Vector3d(1,2,3);
useExtraMethod(basic); // this line works now
}
}
答案 1 :(得分:2)
我不会专注于类层次结构的底层数据结构,而是更多地关注所公开的外部接口。
在您的示例中,Vector3DPlus
类在Vector3D
上找不到其他方法。这使它的接口与基类区分开来,使它们不能完全替代。当基类型传递给期望子类型的方法时,编译器会正确引发异常。
我不相信你可以避免某种形式的类型检查来实现你想要的行为。不知何故,您需要确保只将Vector3DPlus
的实例传递给您的方法。这是向下倾斜的代价。
public static void main(String[] args) {
Vector3d basic=new Vector3d(1,2,3);
if(basic instanceof Vector3dPlus){
useExtraMethod(basic); //this line correctly raises an exception, but is there a way around that
}
}
答案 2 :(得分:0)
这个怎么样?
import javax.vecmath.Vector3d;
public class Vector3dPlus extends Vector3d{
Vector3dPlus {
super(int a, int b, int c);
}
public double extraMethod(){
return x+y+z;
}
}
并使用如下:
import javax.vecmath.Vector3d;
public class Test {
public static void main(String[] args) {
Vector3d basic=new Vector3d(1,2,3);
Vector3dPlus plus=new Vector3dPlus(1,2,3);
useExtraMethod(basic);
useExtraMethod(plus);
}
public static void useExtraMethod(Vector3d vector){
if (vector instanceof Vector3dPlus) {
System.out.println(((Vector3dPlus) vector).extraMethod());
}
}
}
答案 3 :(得分:0)
您可以按照以下说明实现它[如果您不想使用instanceof,则没有其他方法可以实现此目的]:
public class Test {
public static void main(String[] args) {
Vector3dPlus basicPlus = new Vector3dPlus(1,2,3);
Vector3d basic=basicPlus;
useExtraMethod(basic);
}
public static void useExtraMethod(Vector3dPlus plus){
System.out.println(plus.extraMethod());
}
}
Java具有检查类型转换的内部机制。你不能绕过“子类是父类的类”的基本原则,但是“父类不是类型子类”