【问题标题】:How are subclasses of an interface get called如何调用接口的子类
【发布时间】:2017-11-13 10:09:23
【问题描述】:

这是一个困扰我一段时间的问题。

在像 Jersey 这样的框架中,我们有接口,我们可以对这些接口进行子类化以向我们的程序添加一些功能。例如,要在 REST 应用程序中添加请求过滤,我们可以实现 ContainerRequestFilter,然后我们就获得了身份验证。

我的问题是框架/库如何知道我们有其接口的子类之一?

据我了解,您不能实例化接口,只能实例化其子类,例如:

public interface Greeter{
    void sayHi();
}

public class SpanishGreeter implements Greeter{
    @override
    void sayHi(){
        System.out.println("Hola");
    }
}

public class Controller{
   public void main(String[] args){
       //We must know the name of subclass to instantiate?
       Greeter spanishG = new SpanishGreeter();
   }
}

【问题讨论】:

  • 是的。 by new NameOfImplementingClass();
  • 如果我们必须知道名称,那么框架如何实例化它? @Stultuske
  • 什么意思?
  • 这是一个很好的问题,简短的回答是“这很棘手”。没有明显的方法,但你可以看看this project,看看他们是如何做到的。
  • @Stultuske 不一定。请参阅 Spring 自动装配,它会很高兴地实例化接口的任何实现(只要没有其他实现),而无需任何进一步的说明。

标签: java interface dynamic-binding


【解决方案1】:

您正在寻找的是类路径扫描

这不是一项微不足道的任务,正如其名称所说的那样:您基本上需要扫描类路径并加载您找到的每个类(尽管典型的实现将允许您将搜索限制在某些包及其仅限子包,以防止事情变得非常疯狂)。

Java 语言中没有任何特殊技巧可以使这项任务变得简单。

好消息是你不需要从头开始编写它,因为像 Spring 这样的框架已经内置了它,或者如果你想拥有完整的底层控制,你可以使用像 @987654321 这样的专用库@。

【讨论】:

    【解决方案2】:

    我认为 instanceof 关键字有助于它。

    System.out.println(spanishG instanceof Greeter);  // true
    

    【讨论】:

    • 但是为了让它工作 spanishG 必须已经以某种方式实例化了?在我们不知道子类的名称是什么或者是否提供了一个的上下文中
    【解决方案3】:

    这是由于多态性而发生的。你提到的代码

    Greeter spanishG = new SpanishGreeter();
    

    这有父母的参考(在你的情况下是界面)。在运行时它检查天气是否有一个子类实现该方法,如果是,则它调用子类行为。在你的类中,你在运行时用子类实例化 JVM 知道你已经提供了实现。

    【讨论】:

    • 我知道多态性,但是当我们不知道实现类的名称是什么或是否提供了实现时,该实例是如何生成的
    • 这就是多态性。它在运行时检查。
    猜你喜欢
    • 2013-07-24
    • 2014-07-23
    • 2015-07-09
    • 2017-09-28
    • 1970-01-01
    • 2014-01-13
    • 2017-06-05
    • 2016-06-10
    • 2018-08-23
    相关资源
    最近更新 更多