【问题标题】:Use methods declared in implementation that are not defined in interface使用在实现中声明但未在接口中定义的方法
【发布时间】:2012-04-01 17:44:09
【问题描述】:

我有一个由接口定义的类

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 框架未涵盖的依赖项,因此方法会随着实现而变​​化。

【问题讨论】:

    标签: java interface methods upcasting


    【解决方案1】:

    问题出在以下行:

    Test test = new TestImpl();
    

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

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

    TestImpl test = new TestImpl();
    

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

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

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

    【讨论】:

      【解决方案2】:

      使用

      TestImpl test = new TestImpl();
      

      然后

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

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

      【讨论】:

        【解决方案3】:

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

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

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

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

        【讨论】:

          【解决方案4】:

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

          【讨论】:

          • 我认为我们没有足够的信息来确定创建 interface2 是这里的最佳选择。将方法添加到类中可能没问题,这取决于他需要做什么。
          • 是的,我同意你的观点,但问题在于能够通过接口访问 bold 各种 bold 实现。所以你应该记住继承。
          【解决方案5】:

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

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

          【讨论】:

            【解决方案6】:

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

            例如。

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

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

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2015-07-19
              • 1970-01-01
              • 2012-09-01
              • 2021-11-02
              • 1970-01-01
              • 2021-09-30
              • 1970-01-01
              相关资源
              最近更新 更多