Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/363.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 当这些方法的返回类型依赖于子类时,如何强制子类行为/方法? 我想要达到的目标:_Java_Inheritance_Abstract Class - Fatal编程技术网

Java 当这些方法的返回类型依赖于子类时,如何强制子类行为/方法? 我想要达到的目标:

Java 当这些方法的返回类型依赖于子类时,如何强制子类行为/方法? 我想要达到的目标:,java,inheritance,abstract-class,Java,Inheritance,Abstract Class,我试图编写一个抽象类,它是所有子类都应该具有的数据类型和行为的蓝图。但是,这些强制方法的返回类型将取决于子类本身 我的尝试: 在对我的许多封闭式问题之一的评论中,我被告知我在这里所做的是重载我的父方法,而不是重写它们。我理解这是因为我更改了方法签名,@Override要求签名相同,但实现可能不同 public abstract class BaseMatrix { protected int[] shape; protected int nrows; protected

我试图编写一个抽象类,它是所有子类都应该具有的数据类型和行为的蓝图。但是,这些强制方法的返回类型将取决于子类本身

我的尝试: 在对我的许多封闭式问题之一的评论中,我被告知我在这里所做的是重载我的父方法,而不是重写它们。我理解这是因为我更改了方法签名,
@Override
要求签名相同,但实现可能不同

public abstract class BaseMatrix {

    protected int[] shape;
    protected int nrows;
    protected int ncols;

    public BaseMatrix(int rows, int cols){
        this.nrows = rows;
        this.ncols = cols;
        this.shape = new int[]{nrows, ncols};
    }

    // ** here is the method I want to implement/override **
    public abstract BaseMatrix mmul(BaseMatrix other); 
我最初尝试使用泛型来解决这个问题,但发现我对它们的理解不够,无法以这种方式实现解决方案。因此,我采纳了两个类似问题中的建议:和

这将导致
@覆盖处出现警告:

方法不重写其超类中的方法

但是,如果我在子类中使用相同的方法签名:

public class ND4JDenseMatrix extends BaseMatrix{
    public BaseMatrix mmul(BaseMatrix other) { ...implementation...}
}
然后有人可以传递
BaseMatrix
mmul()
的任何子级,这几乎肯定会中断

我的问题 鉴于我知道我正在重载而不是重写,我如何实现问题第一部分中描述的强制将类型传递给子类方法的功能?

这里:

@Override
public ND4JDenseMatrix mmul(ND4JDenseMatrix other) {
Java重写是的共同变体

这意味着:

  • 您可以缩小返回类型的范围(在这里您可以这样做:ND4JDenseMatrix比BaseMatrix更具体)
  • 但您不能缩小参数范围
这就是您在这里要做的:您将方法限制为比基类中的参数类型更具体的参数类型

换句话说,它只能这样工作:

@Override
public ND4JDenseMatrix mmul(BaseMatrix other) {
这才是真正的问题。你看,该方法的调用方被告知它可以传入任何基矩阵。但您希望将其限制为BaseMatrix的更具体的子类型。

此处:

@Override
public ND4JDenseMatrix mmul(ND4JDenseMatrix other) {
Java重写是的共同变体

这意味着:

  • 您可以缩小返回类型的范围(在这里您可以这样做:ND4JDenseMatrix比BaseMatrix更具体)
  • 但您不能缩小参数范围
这就是您在这里要做的:您将方法限制为比基类中的参数类型更具体的参数类型

换句话说,它只能这样工作:

@Override
public ND4JDenseMatrix mmul(BaseMatrix other) {

这才是真正的问题。你看,该方法的调用方被告知它可以传入任何基矩阵。但是您希望将其限制为BaseMatrix的一个更具体的子类型。

假设subject上的继承是一个技术继承,并且不考虑多态性(因为返回值不是
BaseMatrix
类型的多态性),可以使用泛型

public abstract class BaseMatrix<T extends BaseMatrix<T>> {
    protected int[] shape;
    protected int nrows;
    protected int ncols;

    public BaseMatrix(int rows, int cols){
        this.nrows = rows;
        this.ncols = cols;
        this.shape = new int[]{nrows, ncols};
    }

    public abstract T mmul(T other);
}

public class ND4JDenseMatrix extends BaseMatrix<ND4JDenseMatrix> {

    private INDArray data;

    public ND4JDenseMatrix(int rows, int cols) {
        super(rows, cols);
        this.data = Nd4j.zeros(this.shape);
    }

    @Override
    public ND4JDenseMatrix mmul(ND4JDenseMatrix other) {
        INDArray product = this.data.mmul(other.data);
        ND4JDenseMatrix result =  new ND4JDenseMatrix(this.nrows, this.ncols);
        result.setData(product);
        return this;
    }
}
公共抽象类BaseMatrix{
受保护的int[]形状;
受保护的内部流动;
受保护的int NCOL;
公共基矩阵(int行,int列){
this.nrows=行;
this.ncols=cols;
this.shape=newint[]{nrows,ncols};
}
公开摘要T mmul(T其他);
}
公共类ND4JDenseMatrix扩展了BaseMatrix{
私有阵列数据;
公共ND4JDENSE矩阵(int行,int列){
超级(行、列);
this.data=Nd4j.zero(this.shape);
}
@凌驾
公共ND4JDenseMatrix mmul(ND4JDenseMatrix其他){
INDArray product=this.data.mmul(其他.data);
ND4JDenseMatrix结果=新的ND4JDenseMatrix(this.nrows,this.ncols);
结果:设置数据(产品);
归还这个;
}
}

假设subject处的继承是一种技术继承,并且不考虑多态性(因为返回值不是
BaseMatrix
类型的多态性),那么可以使用泛型

public abstract class BaseMatrix<T extends BaseMatrix<T>> {
    protected int[] shape;
    protected int nrows;
    protected int ncols;

    public BaseMatrix(int rows, int cols){
        this.nrows = rows;
        this.ncols = cols;
        this.shape = new int[]{nrows, ncols};
    }

    public abstract T mmul(T other);
}

public class ND4JDenseMatrix extends BaseMatrix<ND4JDenseMatrix> {

    private INDArray data;

    public ND4JDenseMatrix(int rows, int cols) {
        super(rows, cols);
        this.data = Nd4j.zeros(this.shape);
    }

    @Override
    public ND4JDenseMatrix mmul(ND4JDenseMatrix other) {
        INDArray product = this.data.mmul(other.data);
        ND4JDenseMatrix result =  new ND4JDenseMatrix(this.nrows, this.ncols);
        result.setData(product);
        return this;
    }
}
公共抽象类BaseMatrix{
受保护的int[]形状;
受保护的内部流动;
受保护的int NCOL;
公共基矩阵(int行,int列){
this.nrows=行;
this.ncols=cols;
this.shape=newint[]{nrows,ncols};
}
公开摘要T mmul(T其他);
}
公共类ND4JDenseMatrix扩展了BaseMatrix{
私有阵列数据;
公共ND4JDENSE矩阵(int行,int列){
超级(行、列);
this.data=Nd4j.zero(this.shape);
}
@凌驾
公共ND4JDenseMatrix mmul(ND4JDenseMatrix其他){
INDArray product=this.data.mmul(其他.data);
ND4JDenseMatrix结果=新的ND4JDenseMatrix(this.nrows,this.ncols);
结果:设置数据(产品);
归还这个;
}
}

A
ND4JDenseMatrix
是一个
BaseMatrix
,因此您可以将方法签名保留为
public BaseMatrix mmul(BaseMatrix)
,仍然传入并返回一个
ND4JDenseMatrix
@azurefrog,但这不允许用户传入
BaseMatrix
类的任何子级吗?因为如果发生这种情况,结果可能会失败…一个
ND4JDenseMatrix
是一个
BaseMatrix
,因此您可以将方法签名保留为
public BaseMatrix mmul(BaseMatrix)
仍然传入并返回
ND4JDenseMatrix
@azurefrog,但这不允许用户传入
BaseMatrix
类的任何子级吗?因为如果那样的话,结果可能会失败…@GhostCat我明白你的意思,你可能是对的。但这比你在回答中提出的问题更糟糕吗?似乎我必须选择一个问题并接受它…@GhostCat事实上,我假设这里的继承是技术上的(代码重用),而不是真正的多态性。我将把它添加到回答中是的,代码重用是