Java让超类返回扩展类的类型 [英] Java let superclass return type of extended class

查看:216
本文介绍了Java让超类返回扩展类的类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前的情况:
我有一个超类矩阵:

My current situation: I have a superclass Matrix:

public class Matrix {
  private final float[] values;
  private final int numberOfRows;
  private final int numberOfColumns;

  public Matrix(int rows, int columns, float... values) {
    this.values = new float[numberOfRows * numberOfColumns];
    this.numberOfRows = numberOfRows;
    this.numberOfColumns = numberOfColumns;
    System.arraycopy(values, 0, this.values, 0, values.length);
  }

  public Matrix scale(int scaleFactor) {
    //Some code that returns a scaled version of the matrix
  }
}

由Vector类扩展,该类具有一些特定于矢量的方法(例如计算向量的长度) 。

which is extended by the Vector class that has some vector-specific methods (like e.g. calculating the length of the vector).

现在,假设我有一个名为的矢量对象,我想按比例缩放它。然后我会调用 vector.scale(1234); ,这会产生一个矩阵对象。

Now, let's say I have a vector object named, and I want to scale it by some factor. Then I would call vector.scale(1234); which results in a matrix object.

但是,我希望结果是一个矢量对象。我当然可以覆盖Vector类中的scale方法,并将超类的结果强制转换为Vector类的对象,但这似乎不是正确的方法。

However, I would expect the result to be a vector object. I could of course override the scale method in the Vector class and cast the superclass's result to an object of the Vector class, but this doesn't seem like the proper way to do this.

任何人都可以给我一些关于如何实现它的指示,以便我可以扩展Matrix类并让子类的对象在调用它们时返回它们自己的对象类型scale方法?

Could anyone give me some pointers on how to implement this so that I can extend the Matrix class and have objects of the subclasses return their own types of objects when they call the scale method?

推荐答案

如果 Vector extends Matrix ,您可以:

public class Matrix {
    public Matrix scale(int scaleFactor) {
        ... return Matrix ...
    }
}

public class Vector extends Matrix {
    ...

    @Override
    public Vector scale(int scaleFactor) { // <-- return sub type here!
        ... return Vector ...
    }
}

在Java 5中,被覆盖的方法必须具有相同类型的规则已被削弱:您现在可以使用子类型来使覆盖方法更具体。

The rule that overridden methods must have the same type has been weakened in Java 5: You can now use subtypes as well to make overridden methods "more specific."

这种方法优于泛型的优点在于它是干净的,不需要(隐式)强制转换,它完全限制了类型而没有任何泛型魔法。

The advantage of this approach over generics is that it's clean, no (implicit) casting is required and it exactly limits the types without any generics magic.

现在 Vector 只是一种特殊的矩阵(1列/行类型),这意味着 scale()中的代码是相同的。

Now Vector is just a special kind of Matrix (the 1-column/row type) which means that the code in scale() is the same.

不幸的是,这不起作用:

Unfortunately, this doesn't work:

public class Vector extends Matrix {
    ...

    @Override
    public Vector scale(int scaleFactor) { // <-- return sub type here!
        return (Vector) super.scale(scaleFactor);
    }
}

因为你无法投出 Matrix 实例到 Vector 。解决方案是将比例代码移动到辅助方法中:

since you can't cast Matrix instances into a Vector. The solution is to move the scale code into a helper method:

public class Matrix {
    protected void doScale(int scaleFactor) {
        ... original scale() code here...
    }

    public Matrix scale(int scaleFactor) {
        doScale(scaleFactor);
        return this;
    }
}

public class Vector extends Matrix {
    ...

    @Override

    public Vector scale(int scaleFactor) {
        doScale(scaleFactor);
        return this;
    }
}

如果类是不可变的(它可能应该是),那么你需要使用复制构造函数,当然:

If the class is immutable (and it probably should be), then you need to use the copy constructor, of course:

    public Matrix scale(int scaleFactor) {
        Matrix result = new Matrix(this);
        result.doScale(scaleFactor);
        return result;
    }

这篇关于Java让超类返回扩展类的类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆