有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

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

class MyClass extends Parent implements Naming

在这种情况下,我实现了两次多态性:MyClass同时是ParentNaming类型。但我不明白注射是怎么起作用的。这个想法是,在注入期间,我不会使用@Override关键字。我希望问题是清楚的。谢谢

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


共 (2) 个答案

  1. # 1 楼答案

    So I know about polymorphism through interface and and extension such as

    class MyClass extends Parent implements Naming

    这被称为遗传性,而不是多态性MyClassParent,而MyClass也是Naming。也就是说,inheritance允许你实现polymorphism

    考虑除^ {< CD1>}之外的类,也实现^ {CD4>}:

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

    现在考虑一个在代码库中某个地方使用^ {< CD4>}参数的方法:

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

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

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

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

    But I don't get how injection works. The idea is that I would not be using the @Override keyword during injection

    从更广泛的意义上说,这是正确的。为了把某物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方法的单个实现。 `

  2. # 2 楼答案

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

    class Store {
    
        private List l
    
        void store(Object o) {
           l.add(o);
        }
    
        void setStoreProvider(List l) {
            this.l = l
        }
    }
    

    您可以使用setStoreProvider注入用作备份存储的实际List,它可以是链表、数组备份列表等等

    因此,根据注入的类型,你的Store类将具有注入类型的特性(关于内存使用、速度等)

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