How to declare a variable of type Interface and then assign to the variable an object of a Class that implements the Interface, and how to test this?

huangapple go评论72阅读模式
英文:

How to declare a variable of type Interface and then assign to the variable an object of a Class that implements the Interface, and how to test this?

问题

我在处理类与它们实现的接口之间的交互时遇到了困难。具体来说,如何声明一个类型为接口的变量,然后将实现该接口的类的对象赋值给该变量,而该类的构造函数需要参数。我是基于规范来实现的,因此不能只是添加一个不需要参数的构造函数。

我有一个需要两个参数的构造函数和获取方法:

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

然后我有一个方法 "manipulate",它必须以接口作为输入,并将其作为输出返回:

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

从声明一个接口 example 的变量并将实现 example 的 exampleImpl 类的对象分配给该变量的角度来看,我的方法是否有效?它还必须返回一个类型为 example 的变量,但当这发生时,我不知道 newVar1 和 newVar2 去哪里,因为它们在接口中未定义。

我还需要使用 JUnit 4 测试这个方法,但我完全不知道如何做到这一点,因为无法实例化类型为 example 的对象,那么我如何传递参数,例如:

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

这会显示错误,因为 manipulate 不是一个静态方法,但是当它需要一个对象 (this) 来工作时,我怎么能将它变成一个静态方法呢?我是否可以在测试类中创建一个对象来调用这个测试?我想检查它是否根据对象 "this" 和新对象 "e" 返回正确的操作。有没有办法做到这一点?

如果这个问题存在误解,我道歉了。我是一个完全的初学者。我非常难以理解接口的用法,因为规范要求我在这里使用它们。非常感谢您的任何帮助。

英文:

I am struggling with the interaction between classes and interfaces that they implement. Specifically, how to declare a variable of type Interface and then assign to the variable an object of a Class that implements the Interface, when the constructor of the class require parameters. I am implementing this based on a specification, so I cannot just add a constructor which requires no parameters.

I have a constructor, which requires 2 parameters, and getter methods:

public class exampleImpl implements example{

    private int var1;
    private int var2;

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

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

I then have a method "manipulate" which must take the interface as an input and return it as an output:

    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&lt;Integer, Integer&gt; pair  = normaliseExample(newVar1, newVar2);
        int normalisedNewVar1 = pair.getKey();
        int normalisedNewVar2 = pair.getValue();
        example summedE = new exampleImpl(normalisedNewVar1, normalisedNewVar2);
        return summedE;
    }

The interface itself only defines this method as:

public interface example extends Example {

    public example manipulate(example e);
}

Is my method valid in terms of declaring a variable of interface example and then assigning to the variable an object of exampleImpl that implements example? It must also return a variable of type example, but I do not know where newVar1 and newVar2 go when this happens since they are not defined in the interface.

I also need to test this method using JUnit 4 and I am at a complete loss on how to do this, given that you cannot instantiate an object of type example, so how can I pass in parameters e.g:

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

This shows an error because manipulate is not a static method, but how can I make it a static method when it requires an object (this) to work? Can I create an object within the test class to call this test on? I want to check it returns the right manipulation based on an object "this" and the new object "e". Is there a way to do this?

Apologies if this question is wrought with misunderstanding, I am a complete beginner. I am having a very hard time understanding how interfaces can be used as the specification requires me to use them here. Any help would be very appreciated.

答案1

得分: 1

(我会使用大写字母表示类和接口的名称)

在声明一个接口示例的变量并将实现该接口的exampleImpl对象分配给该变量的方法方面,我的方法是否有效?

是的,但在这种情况下,这是不必要的,而且你不应该这样做。你假设通过参数e传入的对象将始终是一个ExampleImpl实例,因为你对该变量进行了硬编码的转换。如果它不是这样的类,你将会得到ClassCastException。在这种情况下,你可以删除这一行:

Example eInst = (ExampleImpl)e;

并且直接使用变量e

它还必须返回一个类型为example的变量,但我不知道在发生这种情况时newVar1和newVar2去哪里,因为它们在接口中没有定义。

你已经编写了这段代码:

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

这将返回一个实现了Example接口的对象。所以在这方面一切都没问题。如果你想使用newVar1newVar2取决于你对manipulate方法的实现和要求。

我可以在测试类内部创建一个对象来调用这个测试吗?

是的,这是正常的做法。在你的测试方法中编写:

Example obj = new ExampleImpl(4, 5);

来创建一个你可以使用的Example对象。你可以这样用不同的Example对象调用manipulate()方法:

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

我想检查它是否根据对象"this"和新对象"e"返回正确的操作。有办法做到这一点吗?

这取决于你的Example接口中定义了哪些其他方法。你已经写过它继承自另一个名为Example的不同接口。基于在那个接口中的定义,你可以这样在你的Example对象上调用其他方法:

Assert.assertEquals(42, obj3.getDifference()); // 或者你拥有的其他任何方法
英文:

(I will use uppercase for the start of class and interface names)

> Is my method valid in terms of declaring a variable of interface example and then assigning to the variable an object of exampleImpl that implements example?

Yes, but in this case it isn't needed and you shouldn't do it like this anyway. You assume that the object coming via the parameter e will always be a ExampleImpl instance because you have a hard coded cast of that variable. If it is not such a class you will get a ClassCastException. In this case you can remove the

Example eInst = (ExampleImpl)e;

line and use the variable e instead.

> It must also return a variable of type example, but I do not know where newVar1 and newVar2 go when this happens since they are not defined in the interface.

You already have written the code

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

which will return an object, which implements the Example interface. So everything is fine here. If you want to use newVar1 and newVar2 depends on your implementation and requirement for the manipulate method.

> Can I create an object within the test class to call this test on?

Yes, that's the normal way to do so. Write

Example obj = new ExampleImpl(4, 5);

in your test method to create an Example object you can work with. You can call the manipulate() method with a different Example object like this:

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

> I want to check it returns the right manipulation based on an object "this" and the new object "e". Is there a way to do this?

That depends on what other methods are defined on your Example interface. You have written that it extends from a different interface, also named Example. Base on what is defined in that interface, you might call other methods on your Example object like this:

 Assert.assertEquals(42, obj3.getDifference()); // or whatever other methods you have

huangapple
  • 本文由 发表于 2020年4月3日 23:21:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/61015092.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定