Как объявить переменную типа Interface, а затем присвоить переменной объект класса, который реализует интерфейс, и как это проверить? - PullRequest
0 голосов
/ 03 апреля 2020

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

У меня есть конструктор, который требует 2 параметра, и методы получения:

public class exampleImpl implements example{

    private int var1;
    private int var2;

    public exampleImpl(int var1, int var2) {
        if(var2< 0) {
            var1 = 1;
            var2 = 1;
        }

    public int getVar1(){
        return Var1;
    }
    public int getVar2(){
        return Var2;
    }

Затем у меня есть метод "манипулировать", который должен принять интерфейс как введите и верните его как вывод:

    public example manipulate(example e) {
        example eInst = (exampleImpl)e;
        int newVar1 = (this.getVar1()*eInst.getVar2() + this.getVar2()*eInst.getVar1());
        int newVar2 = this.getVar2()*eInst.getVar2();
        Pair<Integer, Integer> pair  = normaliseExample(newVar1, newVar2);
        int normalisedNewVar1 = pair.getKey();
        int normalisedNewVar2 = pair.getValue();
        example summedE = new exampleImpl(normalisedNewVar1, normalisedNewVar2);
        return summedE;
    }

Интерфейс сам определяет этот метод только как:

public interface example extends Example {

    public example manipulate(example e);
}

Является ли мой метод допустимым с точки зрения объявления переменной примера интерфейса, а затем присвоение переменной объекта exampleImpl, который реализует пример? Он также должен возвращать переменную типа example, но я не знаю, где newVar1 и newVar2 go, когда это происходит, поскольку они не определены в интерфейсе.

Мне также нужно протестировать этот метод с помощью JUnit 4 и я в полном недоумении, как это сделать, учитывая, что вы не можете создать экземпляр объекта типа example, так как я могу передать параметры, например:

class exampleImplTest {
    @Test
    public exampleImpl testManipulate()
    {
        assertEquals(example,exampleImpl.manipulate(example(3,4)));
    }

Это показывает ошибку, потому что манипулирование не является метод stati c, но как я могу сделать его методом stati c, когда для работы требуется объект (this)? Могу ли я создать объект в классе теста для вызова этого теста? Я хочу проверить, что он возвращает правильные манипуляции, основанные на объекте "this" и новом объекте "e". Есть ли способ сделать это?

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

1 Ответ

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

(я буду использовать верхний регистр для начала имен классов и интерфейсов)

Является ли мой метод допустимым с точки зрения объявления переменной примера интерфейса и последующего присвоения переменная объект exampleImpl, который реализует пример?

Да, но в этом случае это не нужно, и вы все равно не должны делать это так. Вы предполагаете, что объект, поступающий через параметр e, всегда будет экземпляром ExampleImpl, потому что у вас есть жестко закодированное преобразование этой переменной. Если это не такой класс, вы получите ClassCastException. В этом случае вы можете удалить строку

Example eInst = (ExampleImpl)e;

и использовать вместо нее переменную e.

Она также должна возвращать переменную типа example, но я не знаю где newVar1 и newVar2 go, когда это происходит, поскольку они не определены в интерфейсе.

Вы уже написали код

Example summedE = new ExampleImpl(normalisedNewVar1, normalisedNewVar2);
return summedE;

, который будет возвращать объект, который реализует интерфейс Example Так что все хорошо здесь. Если вы хотите использовать newVar1 и newVar2, это зависит от вашей реализации и требований к методу manipulate.

Могу ли я создать объект в классе теста для вызова этого теста?

Да, это нормальный способ сделать это. Напишите

Example obj = new ExampleImpl(4, 5);

в своем методе тестирования, чтобы создать объект Example, с которым вы можете работать. Вы можете вызвать метод manipulate() с другим объектом Example следующим образом:

Example obj = new ExampleImpl(4, 5);
Example obj2 = new ExampleImpl(10, 20);
Example obj3 = obj.manipulate(obj2);

Я хочу проверить, возвращает ли он правильные манипуляции на основе объекта "this" и нового объекта «е». Есть ли способ сделать это?

Это зависит от того, какие другие методы определены в вашем Example интерфейсе. Вы написали, что он выходит из другого интерфейса, также называемого Example. Основываясь на том, что определено в интерфейсе , вы можете вызывать другие методы для вашего Example объекта, например:

 Assert.assertEquals(42, obj3.getDifference()); // or whatever other methods you have
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...