Java polymorphism via runtime injection

I've heard that in Java I can achieve polymorphism through runtime injection. Can someone please show a simple example of how this is done? I search the web, but I can't find anything: maybe I was looking wrong. So I am aware of polymorphism via interface and extension like

class MyClass extends Parent implements Naming

      

in this case I achieve polymorphism twice: MyClass is of type Parent

and at the same time Naming

. But I don't understand how injection works. The idea is that I would not use the keyword @Override

during injection. Hope this question is clear. Thank.

So the end result here, in my understanding, is to change the behavior of the method through injection, not @Override

at design time.

+3


source to share


2 answers


So, I know about polymorphism via interface and extension, like

class MyClass extends Parent implements Naming

This is known as heredity, not polymorphism. MyClass

is Parent

as well MyClass

as is Naming

. This inheritance

allows you to achieve polymorphism

.

Consider a class other than MyClass

that also implements Naming

:

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

     }
 }

      

Now, consider a method that takes an argument Naming

somewhere in your codebase:

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

      

The method doSomething

can be passed an instance of any class

that implements Naming

. Thus, both of the following calls are in effect:

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

      

Note how you can call doSomething

with different parameters. At run time, the first call will call someMethodDefinedInTheInterface

from MyClass

, and the second call will call someMethodDefinedInTheInterface

from SomeOtherClass

. This is called runtime-polymorphism

, which can be achieved through inheritance.

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



This is true in a broader sense. For inject

something to be in class, the class must ideally support composition

over inheritance

. See this answer, which does a good job of explaining why composition is preferred over inheritance.

To expand on the above example from my answer, change the method doSomething

as follows:

  public class ClassHasANaming {
      private Naming naming;

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

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

      

Observe how it now ClassHasANaming

has a dependency Naming

that can be injected from the outside world:

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

      

If you are using the Factory pattern , you can actually choose which subclass will be created at startup.

Do you think we could do what we did above using inheritance

?

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

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

      

The answer is no . ClassIsANaming

tied to one implementation of the method someMethodDefinedInTheInterface

at compile time. `

+2


source


Taking a contrived example. You have a class Store

that stores things:

class Store {

    private List l

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

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

      

You can enter the actual List

used as the backup storage using setStoreProvider

which can be a linked list, an array with a backup list, etc.



Hence, depending on the injected type, your class Store

will have properties of the injected type (regarding memory usage, speed, etc.).

It's kind of polymorphism without a class implementing the interface.

+1


source







All Articles