使用实现中声明的接口中未定义的方法

我有一个由接口定义的类

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

我该如何调用anotherMethod?

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

我希望能够在实现中定义一些方法,因为在我的生产代码中,Test接口涵盖了相当广泛的类,并由多个类实现。 我使用实现中定义的方法来设置unit testing中DI框架未涵盖的依赖关系,因此方法从实现变为实现。

问题出在以下几行:

 Test test = new TestImpl(); 

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

你所做的被称为“向上转换”(将对象转换为更通用的类型)。 正如另一张海报所说,你可以通过不上传来修复你的问题:

 TestImpl test = new TestImpl(); 

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

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

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

使用

 TestImpl test = new TestImpl(); 

然后

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

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

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

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

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

 SpecificTest test = new TestImpl(); test.anotherMethod(); 

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

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

 Test test = new TestImpl(); // ... and later / somewhere else ((TestImpl) test).anotherMethod(); 

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

例如。

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

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