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

时间:2012-03-16 06:29:10

标签: java interface methods upcasting

我有一个由接口

定义的类
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接口涵盖了相当广泛的类,并由多个类实现。我使用实现中定义的方法来设置单元测试中DI框架未涵盖的依赖关系,以便方法从实现变为实现。

6 个答案:

答案 0 :(得分:6)

问题出在以下几行:

Test test = new TestImpl();

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

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

TestImpl test = new TestImpl();

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

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

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

答案 1 :(得分:2)

使用

TestImpl test = new TestImpl();

然后

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

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

答案 2 :(得分:2)

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

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

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

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

答案 3 :(得分:1)

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

答案 4 :(得分:0)

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

Test test = new TestImpl();

// ... and later / somewhere else

((TestImpl) test).anotherMethod();

答案 5 :(得分:0)

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

例如。

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

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