Разработка примера для старшеклассников о Java-интерфейсах - PullRequest
0 голосов
/ 03 апреля 2019

Я хочу создать пример интерфейса Java с именем NUMBER, который реализуют два класса Java FRACTION и COMPLEX.У меня проблема с тем, чтобы заставить его работать.

Например: у меня есть метод FRACTION, называемый add со следующим заголовком -

public Fraction add(Fraction f) 

, и метод COMPLEX, называемый add, со следующимheader -

public Complex add(Complex c).

Когда я определяю метод в интерфейсе как

public Object add(Object o) 

и компилирую Fraction, я получаю ошибку, что мой метод Fraction не перезаписывает абстрактный метод в интерфейсеNUMBER.

Ответы [ 3 ]

1 голос
/ 03 апреля 2019

Проблема в том, что при компиляции Java видит, что в интерфейсе есть метод с именем add, который выводит Object, но в реализующем классе он не находит никакого имени метода add, которое возвращает Object. Вместо этого вы могли бы заставить метод интерфейса возвращать Number и приводить выходные данные на основе этого. Вы должны иметь в виду, что все методы должны возвращать этот тип Number.

Другим вариантом может быть использование дженериков. Я не совсем уверен, как работает переопределение методов с универсальными типами, но вы можете использовать что-то похожее в вашем Number классе:

<T> T add(T t);

Я не совсем уверен, сработает ли это, поскольку я не очень много работал с обобщениями в интерфейсах, но это возможно.

Вы также можете сделать что-то вроде этого:

public interface Number<T extends Number> {
    T add(T t);
}

Фракция:

public class Fraction implements Number<Fraction> {
    @Override public Fraction add(Fraction f) {
        ...
    }
}

Фракция:

public class Complex implements Number<Complex> {
    @Override public Complex add(Complex c) {
        ...
    }
}

Выполнение этого позволит вам определить методы, используя более конкретные типы, и должно работать достаточно хорошо, но две вещи заключались бы в том, что я не уверен, считается ли это «наилучшей практикой» для включения одного и того же класса в интерфейс. типа, и если вам удобно показывать вашим ученикам общие типы. Это довольно простая, но мощная концепция, но если вам не нужно объяснять, самое первое решение подойдет вам лучше всего.

1 голос
/ 03 апреля 2019

Ваш интерфейс должен иметь Тип Generic , чтобы соответствовать требованиям метода интерфейса тип возвращаемого значения и тип аргумента , проверьте код ниже:

Сначала вы должны определить общий интерфейсный класс Number как:

package com.oop.concepts;

public interface Number<T extends Number> {
    T add(T t);
}

После того, как у вас есть Generic add с возвращаемым типом T и аргументом TypeВы можете реализовать его, как показано ниже:

package com.oop.concepts;

public class Fraction implements Number<Fraction> {

    private float a;

    public Fraction(float a) {
        this.a = a;
    }

    @Override
    public String toString() {
        return "Fraction{" +
            "a=" + a +
            '}';
    }

    @Override
    public Fraction add(Fraction n) {
        return new Fraction(this.a + n.a);
    }
}

То же самое для сложного класса:

package com.oop.concepts;

public class Complex implements Number<Complex> {

    private Double x;
    private Double y ;

    public Complex (Double x, Double y) {
        this.x = x;
        this.y = y;
    }

    @Override
    public String toString() {
        return "Complex{" +
            "x=" + x +
            ", y=" + y +
            '}';
    }

    @Override
    public Complex add(Complex n) {
        return new Complex(this.x + n.x, this.y + n.y);
    }
}

Тестовый класс:

package com.oop.concepts;

public class TestNumber {

    public static void main (String args[]) {

        Complex c1 = new Complex(3.4, 56.78);
        Complex c2 = new Complex(3.4, 56.78);

        Complex c3 = c1.add(c2);

        System.out.println(c3);

        Fraction f1 = new Fraction(3.4f);
        Fraction f2 = new Fraction(1.0f);
        Fraction f3 = f1.add(f2);

        System.out.println(f3);


    }
}

Вывод вышеприведенных тестовых примеров:

Complex{x=6.8, y=113.56}
Fraction{a=1.0}
Fraction{a=4.4}

Надеюсь, что это дает четкое понимание концепции ООП наряду с Общими принципами в JAVA

Я вставил этот код в github, посмотрите

0 голосов
/ 03 апреля 2019

Как отмечают некоторые комментарии, подписи ваших методов не могут изменяться.

Как показывает ваш пример, вы поместите один и тот же код в оба класса, что не демонстрирует наследования наилучшим образом.

Один пример, который я использовал и видел много раз, - это использование площади и периметра фигур. Для краткости мой пример показывает только пример одного метода, предполагая, что переменные и конструкторы были сделаны правильно.

public interface Shape{
    public abstract double area();
    public abstract double volume();
}
public class Rectangle implements Shape {
    ...
    public double area() {
        return width * height;
    }
    ...
}
public class Circle implements Shape {
    ...
    public double area() {
        return Math.PI * Math.pow(radius, 2);
    }
    ...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...