3

我有一个由接口定义的类

public interface Test {
    void testMethod();
}

Test test = new TestImpl();

public class TestImpl implements Test {
    @Override
    public void testMethod() {
         //Nothing to do here
    }

    public void anotherMethod() {
        //I am adding this method in the implementation only.
    }
}

如何调用另一个方法?

test.anotherMethod(); //Does not work.

我希望能够在实现中定义一些方法,只是因为在我的生产代码中,Test 接口涵盖了相当广泛的类并且由多个类实现。我使用实现中定义的方法来设置在我的单元测试中 DI 框架未涵盖的依赖项,因此这些方法会随着实现而变​​化。

4

6 回答 6

6

问题出在以下行:

Test test = new TestImpl();

这告诉编译器忘记新对象是 TestImpl 并将其视为普通的旧测试。如您所知,Test 没有 anotherMethod()。

您所做的称为“向上转换”(将对象转换为更通用的类型)。正如另一位海报所说,您可以通过不向上转换来解决您的问题:

TestImpl test = new TestImpl();

如果你确定一个 Test 对象确实是一个 TestImpl,你可以向下转换它(告诉编译器它是一个更具体的类型):

Test test = new TestImpl();
:
((TestImpl) test).anotherMethod();

然而,这通常是一个坏主意,因为它可能导致 ClassCastException。使用编译器,而不是反对它。

于 2012-03-16T06:35:08.807 回答
2

采用

TestImpl test = new TestImpl();

然后

test.anotherMethod();//It will work now

我认为通过您的接口参考,不可能调用该接口中未定义的任何方法。

于 2012-03-16T06:31:13.350 回答
2

如果您想避免直接转换为您的实现类,我会创建另一个接口:

public interface SpecificTest extends Test { 
    void anotherMethod();
}

然后让您的 TestImpl 实现该接口(这意味着您可以将其声明为 Test 或 SpecificTest ):

SpecificTest test = new TestImpl();
test.anotherMethod();
于 2012-03-16T15:27:46.550 回答
1

当然,您可以按照上面的回答访问您的方法,但您应该遵守编程的最佳实践。因此,如果您无法向 Interface1 添加所需的方法,请创建扩展 Inteface1 的 Interface2 并最后添加您的方法。

于 2012-03-16T12:06:36.397 回答
0

如果您强制转换为实现该方法的实现类,则可以调用它简而言之:

Test test = new TestImpl();

// ... and later / somewhere else

((TestImpl) test).anotherMethod();
于 2012-03-16T06:34:42.790 回答
0

如果您不想将其类型转换为具体类,那么您可以将 anotherMethod() 作为私有方法并根据某些逻辑在 testMethod() 中调用它。

例如。

testMethod()
{
   if(foo)
  {
     anotherMethod();
  }
}

如果您不想在子类中创建新方法,则可以使用此解决方法,因为您不能使用父类/接口引用来调用它们。

于 2015-05-07T18:04:50.503 回答