在运行时通过注入实现Java多态性

时间:2015-06-13 10:18:13

标签: java polymorphism code-injection

我听说在Java中我可以通过在运行时注入来实现多态性。有人可以举一个简单的例子来说明这是怎么做的吗?我在网上搜索但我找不到任何东西:也许我错了。所以我通过接口和扩展知道了多态性,比如

class MyClass extends Parent implements Naming

在这种情况下,我实现了两次多态:MyClass类型为ParentNaming。但我不知道注射是如何起作用的。我的想法是在注入期间我不会使用@Override关键字。我希望这个问题很清楚。感谢。

因此,根据我的理解,最终结果是在开发过程中通过注入而不是@Override更改方法的行为。

2 个答案:

答案 0 :(得分:2)

  

所以我通过接口和扩展知道了多态性,比如

     

class MyClass extends Parent implements Naming

这被称为无关,而不是多态。 MyClassParentMyClass也是Naming。话虽如此,inheritance允许您实现polymorphism

考虑MyClass以外的其他类,它也实现了Naming

class SomeOtherClass implements Naming {
     @Override
     public void someMethodDefinedInTheInterface() {

     }
 }

现在考虑一个在代码库中某处带有Naming参数的方法:

public void doSomething(Naming naming) {
     naming.someMethodDefinedInTheInterface();
}

doSomething方法可以传递实现class的任何Naming的实例。因此以下调用都是有效的:

doSomething(new MyClass());//1
doSomething(new SomeOtherClass());//2

观察如何使用不同参数调用doSomething。在运行时,第一个来电将从someMethodDefinedInTheInterface拨打MyClass,第二个来电将从someMethodDefinedInTheInterface拨打SomeOtherClass。这被称为runtime-polymorphism,可以通过继承来实现。

  

但我不知道注射是如何起作用的。我的想法是在注入期间我不会使用@Override关键字

广义上说这是真的。要将inject内容添加到课程中,该课程应该优先于composition而不是inheritance。请参阅this答案,该答案在解释有利于组合而不是继承的原因方面做得很好。

要从我的回答中扩展上述示例,让我们按如下方式修改doSomething方法:

  public class ClassHasANaming {
      private Naming naming;

      public ClassHasANaming(Naming naming) {
          this.naming = naming;
      }

      public void doSomething() {
           naming.someMethodDefinedInTheInterface();
      }
  }

观察ClassHasANaming现在如何拥有Naming依赖关系,可以注入来自外部世界:

ClassHasANaming callMyClass = new ClassHasANaming(new MyClass());
callMyClass.doSomething();

如果使用Factory pattern,您实际上可以选择在运行时实例化哪个子类。

您认为我们可以使用inheritance完成上述操作吗?

 public class ClassIsANaming implements Naming {
    public void doSomething() {
        someMethodDefinedInTheInterface();
    }

    @Override
    public void someMethodDefinedInTheInterface() {
        //....
    }
 }

答案是ClassIsANaming在编译时本身绑定到someMethodDefinedInTheInterface方法的单个实现。        `

答案 1 :(得分:1)

采取一个人为的例子。你有一个存储东西的类Store

class Store {

    private List l

    void store(Object o) {
       l.add(o);
    }

    void setStoreProvider(List l) {
        this.l = l
    }
}

您可以使用List注入用作后备存储的实际setStoreProviderStore可以是链接列表,数组支持列表等等。

因此,根据注入的类型,您的<script src="js/jquery-1.2.1.min.js" type="text/javascript"></script> <script src="js/fullcalendar/jquery.min.js" type="text/javascript"></script> 类将具有注入类型的功能(关于内存使用,速度等)。

这是一种没有实现接口的类的多态性。