2

I am curious regarding java object copies and inheritance. Lets say I have the following two classes:

abstract class Algorithm {
  public abstract void run();
}

class Specialized extends Algorithm {
  @Override
  public void run();
}

Now I want to test the specialized algorithm. And I really want to do this in parallel with multiple instances / parameters. The problem is that the run method is not reentrant, so I have to have per-thread instances of Specialized. Of course any kind AlgorithmRunner should work with the abstract class Algorithm to be able to test multiple different specializations. The problem is that I would need to construct a new ? extends Algorithm from an existing one in a generic fashion. How can I achieve this? I could easily write copy constructors for each kind of specialization but that would require switches using instanceof checks which I would rather avoid.

hfhc2
  • 4,182
  • 2
  • 27
  • 56
  • 2
    You can't have an abstract method in a non-abstract class. Try to have your examples correct, so we are sure what you are talking about (an abstract class, or a non-abstract method, for instance) – Stultuske Apr 27 '15 at 12:05
  • Would using `Object.clone()` be an option? http://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#clone-- – blalasaadri Apr 27 '15 at 12:06
  • Well, many people seem to be opposed to cloning (http://www.javapractices.com/topic/TopicAction.do?Id=71) and I see their points... – hfhc2 Apr 27 '15 at 12:07
  • possible duplicate of [How do I copy an object in Java?](http://stackoverflow.com/questions/869033/how-do-i-copy-an-object-in-java) – Joe Apr 27 '15 at 12:10

2 Answers2

3

There are a couple of ways to do this. One is to have Algorithm have an abstract factory method for getting instances:

abstract class Algorithm {
  public abstract void run();

  protected abstract Algorithm buildInstance();
}

class Specialized extends Algorithm {
  @Override
  public void run() {
      // ...
  }

  @Override
  protected Algorithm buildInstance() {
      return new Specialized();
  }
}

FWIW, I would lean toward having an AlgorithmRunner separate from Algorithm, and have it accept an instance of an AlgorithmCreator or similar with the factory method.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
3

You could try using the Factory pattern:

interface AlgorithmFactory {
    public abstract Algorithm createAlgorithm();
}

class SpecializedFactory implements AlgorithmFactory {
    @Override
    public Specialized createAlgorithm() {
        return new Specialized();
    }
}

Then passing an AlgorithmFactory to AlgorithmRunner allows it to instantiate the subclass of Algorithm without knowing its implementation.

hugh
  • 2,237
  • 1
  • 12
  • 25