Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/368.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
通过运行时注入实现Java多态性_Java_Polymorphism_Code Injection - Fatal编程技术网

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

通过运行时注入实现Java多态性,java,polymorphism,code-injection,Java,Polymorphism,Code Injection,我听说在Java中,我可以在运行时通过注入实现多态性。有人能举一个简单的例子说明这是如何做到的吗?我在网上搜索,但什么也找不到:也许我搜索错了。所以我通过接口和扩展了解多态性,比如 class MyClass extends Parent implements Naming 在这种情况下,我实现了两次多态性:MyClass的类型同时是Parent和Naming。但我不明白注射是怎么起作用的。我的想法是,在注入期间,我不会使用@Override关键字。我希望问题是清楚的。谢谢 因此,根据我的理解

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

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

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

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

class MyClass extends Parent implements Naming
class MyClass扩展父级实现命名

这被称为遗传性,而不是多态性
MyClass
是一个
父类
MyClass
也是一个
命名
。也就是说,
继承
允许您实现
多态性

考虑一个类,而不是
MyClass
,它也实现了
命名

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

     }
 }

现在考虑一个方法,在代码库中的某个地方使用<代码>命名< /C> >参数:

public void doSomething(Naming naming) {
     naming.someMethodDefinedInTheInterface();
}
doSomething
方法可以传递实现
命名的任何
类的实例。因此,以下两个调用都是有效的:

doSomething(new MyClass());//1
doSomething(new SomeOtherClass());//2
观察如何使用不同的参数调用
doSomething
。在运行时,第一个调用将从
MyClass
调用接口定义的
somemethods
,第二个调用将从
SomeOtherClass
调用接口定义的
somemethods
。这被称为运行时多态性,可以通过继承来实现

但我不明白注射是怎么起作用的。我的想法是在注入过程中不会使用@Override关键字

从广义上讲,这是正确的。为了
向类中注入
某种东西,类在理想情况下应该倾向于
组合
而不是
继承
。请参阅答案,它很好地解释了支持组合而不是继承的原因

为了从我的答案中扩展上述示例,让我们修改
doSomething
方法如下:

  public class ClassHasANaming {
      private Naming naming;

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

      public void doSomething() {
           naming.someMethodDefinedInTheInterface();
      }
  }
观察
ClassHasANaming
现在如何拥有一个可以从外部世界注入的
命名依赖关系:

ClassHasANaming callMyClass = new ClassHasANaming(new MyClass());
callMyClass.doSomething();
如果使用,实际上可以选择在运行时实例化哪个子类

您认为我们可以使用
继承
完成上面的工作吗

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

    @Override
    public void someMethodDefinedInTheInterface() {
        //....
    }
 }
答案是否定的
ClassisAnming
在编译时绑定到接口
方法定义的
SomeMethods的单个实现。

`举一个人为的例子。您有一个存储物品的类
Store

class Store {

    private List l

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

    void setStoreProvider(List l) {
        this.l = l
    }
}
您可以使用
setStoreProvider
注入实际的
列表
,该列表可以是链表、阵列备份列表等

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


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

“…在这种情况下,我实现了两次多态性:MyClass同时是Parent和Naming类型”这不是“多态性”的意思。我知道你是怎么到那里的,但那不是它的意思。您可能需要查看一些OOP教程。@T.J.Crowder如果您提供更正而不是简单地指出错误,您的评论可能会更有用。谢谢。多态性在SO评论中是无法合理解释的,这就是我建议使用教程的原因。你从哪里听说的?一些网站(如果有请提供链接)?或者有人没有进一步解释就告诉你了?
List
在这里是多态的,而不是
Store
<代码>存储
只是一个使用(多态)接口的客户端<如果
DatabaseStore
将其扩展为覆盖
Store
方法以向数据库添加对象,则code>Store
将是多态的。例如,我知道有人会提出这个问题。Store正在实现多态行为,即使根据正常的Java定义,它不是多态的。最后,带有子类的超类在内部的工作方式(或多或少)与存储和列表组合相同。