7

我有一种感觉,这是不可能的,但如果不是,它会非常有用。

我试图以子类只有新方法,没有新构造函数,没有新字段的方式扩展父类。所以子类的底层数据结构和父类是一样的。当我想为内置的 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方法适用于 all Vector3d。但是,无论如何我可以对 java 说底层数据结构是相同的,因此允许所有从 all 向下转换Vector3dVector3dPlus.

我目前处理这个问题的方法是将所有额外的方法放在通用实用程序类中,但这显然有点可怕

4

4 回答 4

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
        }
    }
于 2013-04-29T09:16:32.487 回答
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
       }
}
于 2013-04-29T09:10:03.023 回答
0

You can achieve it as explained below [there is no other way to achieve this if you dont want to use instanceof that is]:

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 has internal mechanism to check type casting. You can't bypass the basic fundamental of "child class is of type parent class" but "Parent class is not of type child class"

于 2013-04-29T09:37:02.630 回答
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());
        }
    }
}
于 2013-04-29T09:13:59.573 回答