Ява. Почему я не могу преобразовать объект интерфейса в объект класса?

У меня есть этот интерфейс:

public interface Numeric {
    public Numeric addition(Numeric x,Numeric y);
    public Numeric subtraction(Numeric x,Numeric y);
}

И этот класс:

public class Complex implements Numeric {
    private int real;
    private int img;

    public Complex(int real, int img) {
        this.real = real;
        this.img = img;
    }

    public Numeric addition(Numeric x, Numeric y) {
        if (x instanceof Complex && y instanceof Complex) {
            Complex n1 = (Complex)x;
            Complex n2 = (Complex)y;

            return new Complex(n1.getReal() + n1.getReal(), n2.getImg() + 
            n2.getImg());                 
        } 
        throw new UnsupportedOperationException();
    }

    public Numeric subtraction(Numeric x, Numeric y) {
        if (x instanceof Complex && y instanceof Complex) {
            Complex n1 = (Complex)x;
            Complex n2 = (Complex)y;

            return new Complex(n1.getReal() - n1.getReal(), n2.getImg() - 
            n2.getImg());                 
        } 
        throw new UnsupportedOperationException();
    }

    public int getReal() {
        return real;
    }

    public int getImg() {
        return img;
    }
}

Почему я получаю эту ошибку:

несовместимые типы: числовые нельзя преобразовать в комплексные

когда я запускаю этот код:

public class TestNumeric {
    public static void main(String[] args) {
        Complex c1 = new Complex(3, 4);
        Complex c2 = new Complex(1, 2);
        Complex rez;

        rez = rez.addition(c1, c2);
    }
}

Ошибка в строке "rez = rez.addition(c1, c2);"
Комплекс реализует Numeric, поэтому каждый Numeric является комплексом, верно? Я уже сделал кастинг и проверку внутри метода сложения. Почему я получаю эту ошибку и как ее исправить?


person Community    schedule 09.12.2019    source источник
comment
Complex implements Numeric, so every Numeric is a Complex - нет, каждый Complex есть Numeric. Обратное неверно.   -  person Eran    schedule 09.12.2019
comment
Нет, это неправильно. Наоборот: каждый Complex есть Numeric.   -  person stevecross    schedule 09.12.2019
comment
Лично я бы добавил еще один параметр, а не два   -  person Hovercraft Full Of Eels    schedule 09.12.2019
comment
Однако метод добавления не может быть статическим, потому что это метод интерфейса.   -  person RealSkeptic    schedule 09.12.2019
comment
Ваш код не в порядке, потому что rez не инициализирован. Если вы установите rez типа Numeric (и фальшиво инициализируете переменную переменной, чтобы избежать NPE), ваш код скомпилируется. Это нормально: Numeric rez = c1.addition(c1, c2); но, как говорят другие, вероятно, было бы лучше изменить свой метод и сделать так: Numeric rez = c1.addition(c2);   -  person Ermal    schedule 09.12.2019
comment
Ответ на ваш предыдущий вопрос уже объясняет, что каждый числовой объект не является сложным. Поскольку вы сделали свой метод addition возвращаемым типом Numeric, вы не можете назначить его переменной типа Complex .   -  person Sotirios Delimanolis    schedule 09.12.2019
comment
Предполагая, что имеет смысл добавлять числовые значения одного и того же типа, это должно быть общим: interface Numeric<T> { T addition(T x, T y); T subtraction(T x, T y); }, а затем class Complex implements Numeric<Complex> { ... }.   -  person kaya3    schedule 04.02.2020


Ответы (1)


Объявление addition и subtraction должно быть следующим:

public interface Numeric {
    public Numeric addition(Numeric obj);

    public Numeric subtraction(Numeric obj);
}

а реализация addition и subtraction должна быть следующей:

public Numeric addition(Numeric obj){
    if (obj instanceof Complex){
        Complex n = (Complex)obj;

        return new Complex(this.getReal() + n.getReal(), this.getImg() + 
        n.getImg()); 
    } else {
        throw new UnsupportedOperationException();
    }
}

Наконец, TestNumeric должно быть следующим:

public class TestNumeric {
    public static void main(String[] args) {
        Numeric c1 = new Complex(3, 4);
        Numeric c2 = new Complex(1, 2);
        Numeric rez = c1.addition(c2);
    }
}

[Обновление]

@OrosTom - Основываясь на вашем комментарии, я добавил ниже метод, который вам нужно поместить внутри класса, Complex, чтобы вы могли распечатать результат

@Override
public String toString() {
    return real + " + " + img + "i";
}

Примечание: проверьте https://docs.oracle.com/javase/tutorial/java/IandI/objectclass.html (раздел Метод toString()) для получения дополнительной информации.

После этого вывод следующего кода

public class TestNumeric {
    public static void main(String[] args) {
        Numeric c1 = new Complex(3, 4);
        Numeric c2 = new Complex(1, 2);
        Numeric rez = c1.addition(c2);
        System.out.println(c1);
        System.out.println(c2);
        System.out.println(rez);
    }
}

будет:

3 + 4i
1 + 2i
4 + 6i
person Arvind Kumar Avinash    schedule 09.12.2019
comment
Я понимаю, что иметь только один параметр намного лучше. Но я все еще получаю эту ошибку. - person ; 09.12.2019
comment
@ArvindKumarAvinash - Кажется, что создание rez типа Numeric решает ошибку. Но почему я должен это делать? Это сбивает с толку. И после, как мне распечатать результат, если он числового типа? - person ; 09.12.2019
comment
Пожалуйста, проверьте раздел [update] ответа. - person Arvind Kumar Avinash; 04.02.2020