Метод компилируется и работает с неверным типом переданной переменной - PullRequest
0 голосов
/ 09 октября 2018

Итак, вот часть кода, который я тестирую:

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));
    }
}

Он отлично работает и возвращает true, хотя должен был написать исключение, что ожидался VectorNDпри вызове Compare от A. В чем может быть проблема?

1 Ответ

0 голосов
/ 09 октября 2018

Проблема в том, что вы не переопределяете метод Compare() базового класса Vector в VectorND и Vector3D.Вместо этого вы объявляете новые методы, которые принимают объект того же типа (VectorND или Vector3D) в ваших подклассах.Оригинальный метод Compare() базового класса все еще доступен в подклассах, и именно этот метод вызывается при вызове 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)

и в классе VectorND не объявлено Compare(Vector3D), то вы действительно звоните

Vector.Compare(Vector)

, так как обаA и B являются производными от базового класса Vector.

Если вы действительно хотите переопределить метод Compare в Vector на методы в ваших подклассах, вам нужно объявить их идентично в подклассах (то есть с тем же типом параметра).

И если вы действительно хотите, чтобы метод вызывал исключение в указанном случае, вам нужно явно проверить тип Vector с помощью оператора instanceof и вызвать исключение, еслиэто не тот тип.

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 указывает, что вы намеревались переопределить метод в базовом классе.Если в базовом классе нет подходящего метода, например, если вы попытаетесь выполнить

@Override
public boolean Compare(Vector3D vec)

, компилятор / IDE выдаст ошибку, чтобы уведомить вас, что вы ничего не переопределяете (поскольку Vector класс не имеет Compare(Vector3D vec) метода).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...