方法编译并使用传递的错误类型的变量

Method compiles and works with wrong type of variable passed

下面是我正在测试的部分代码:

interface sample
{
    Vector Sum(Vector vec);
    Vector Subtraction(Vector vec);
    int Product(Vector vec);
    boolean Compare(Vector vec);
    String ToString();
}

abstract class Vector implements sample
{       
     int[] coordinates; 
     public Vector (int[] coordinates)
     {
         this.coordinates=coordinates;
     }
}

abstract Vector resVec();

public boolean Compare(Vector vec)
{
    if (this.coordinates.length == vec.coordinates.length)
    {
        for (int i = 0; i<vec.coordinates.length; i++)
        {
            if (this.coordinates[i] == vec.coordinates[i])
                continue;
            else return false;
        }
    }
    else 
    {
        throw new ArithmeticException("Can't compare vectors of different length");
    }
    return true;
}

这里是 类 我调用的方法来自: 1)

class Vector3D extends Vector
{

public Vector3D(int n1,int n2,int n3) 
{
    super(new int[]{n1,n2,n3});
}
public Vector3D resVec()
{
    Vector3D resVec = new Vector3D(0,0,0);
    return resVec;
}

public boolean Compare(Vector3D vec)
{
    return super.Compare(vec);
}

2)

class VectorND extends Vector
{
    public VectorND(int...n) 
    {       
            super(n);
    }
    public VectorND resVec()
    {
        VectorND resVec = new VectorND();
        return resVec;
    }

    public boolean Compare(VectorND vec)
      {
          return super.Compare(vec);
      }
}

所以问题是,出于某种原因,如果我在 main 中写这样的东西:

public class main {

    public static void main(String[] args) 
    {
        Vector3D B = new Vector3D(1,-3,3);
        VectorND A = new VectorND(1,-3,3);
        System.out.println(A.Compare(B));
    }
}

它完美地工作并且 returns 正确,虽然它应该编写一个异常,即在 A 的比较调用中预期 VectorND。可能是什么问题?

问题是您没有覆盖 VectorNDVector3D 中基础 class VectorCompare() 方法。相反,您在子 class 中声明采用相同类型(VectorNDVector3D)对象的新方法。基础 class 的原始 Compare() 方法在子 class 中仍然可用,当您调用 A.Compare(B).

时,它就是被调用的方法

为了更清楚,你有

Vector{
    public boolean Compare(Vector vec){ ... }
}

class Vector3D extends Vector {
    public boolean Compare(Vector vec){ ... }
    public boolean Compare(Vector3D vec){ ... } 
}

class VectorND extends Vector {
    public boolean Compare(Vector vec){ ... }
    public boolean Compare(VectorND vec){ ... } 
}

所以当你打电话给

A.Compare(B)

而且 class VectorND 中没有声明 Compare(Vector3D),你真正做的是调用

Vector.Compare(Vector)

因为 AB 都是从基数 class Vector 派生的。

如果你真的想用你的子class中的方法覆盖Vector中的Compare方法,你需要在子[=56=中相同地声明它们]es(即具有相同类型的参数)。

如果你真的想要方法在指定的情况下抛出异常,你需要使用[=]显式检查Vector的类型31=]运算符,如果不是同一类型则抛出异常。

public class Vector3D extends Vector {
    @Override
    public boolean Compare(Vector vec){
        if( !(vec instanceof Vector3D) )
            throw new IllegalArgumentException("Vector3D can only be compared to Vector3D!");

        // Compare and return true or false
    }
}

@Override 注释表示您打算覆盖基 class 中的方法。如果基class中没有匹配的方法,比如你尝试做

@Override
public boolean Compare(Vector3D vec)

compiler/IDE 将发出错误通知您您没有覆盖任何内容(因为 Vector class 没有 Compare(Vector3D vec) 方法)。