4

In Java, is there any way to create an instance of any class that extends abstract class A, inside a member method of class A? Classes that extends abstract class A will return their instances with this method, but i don't want to implement same method in all subclasses with a "return this();" kind line.

EDIT: Ok sorry for the short explanation. In my application, there is an interface called Application, and it has a getInstance() method that returns an Application type. There is an abstract class called AbstractApplication which is a convenience class for Application interface for implementation, but only the interface is exposed in other apps. In some other apps, there will be a lookup for application objects, and this lookup will return an Application type (interface), not a specific implementation. Now here's my question; is there a way to implement getInstance() in AbstractApplication class so subclasses does not need to implement this method?

5
  • 1
    Care to provide some pseudo code for what you are trying to achieve? Commented Jun 8, 2010 at 21:38
  • 2
    Either its too late, or it's really not yet clear what you want to do. Could you try to give an example (code)? I'm sure it should be possible, but alas, I don't really understand what you want to do in the first place. Commented Jun 8, 2010 at 21:40
  • The question would be, why would you need something that just returns itself? Commented Jun 8, 2010 at 21:52
  • 1
    @Andrei I think the question needs to be interpreted as a method that returns an new instance of the same implementation class. Commented Jun 8, 2010 at 21:54
  • 1
    The only question I have is, who creates the application in first place? For the scenario where your don't know the application until runtime you may use the Prototype design pattern. See my answer below. Commented Jun 9, 2010 at 0:14

5 Answers 5

9

Yeap. That's pretty easy ( unless I misunderstood )

You have to use the Prototype design pattern ( or a variation of it that I show here )

It is useful when you don't know what the factory class could be until runtime. Unlike AbstractFactory where you can have different subclasses creating new types but you may pick one based on certain conditions.

With prototype you may simple get the "original" object ( the prototype ) injected into your application ( by virtue of a full futured Dependency Injection framework or by a simple class name ) and then create new instances of it.

Here's a sample code showing how to do this with a variation ( not using clone but newInstance method )

public abstract class Application {
    public Application newInstance() {
        try {
            return this.getClass().newInstance();//this creates an instance of the subclass 
        } catch( InstantiationException ie ){
            throw new RuntimeException( ie );
        } catch( IllegalAccessException iae ){
            throw new RuntimeException( iae );
        }
    }
    public String toString() {
        return "This is the class named: \""+ this.getClass().getSimpleName()+"\"";
    }
} 
// subclasses doesn't repeat the creation part
// they just have to override specific methods. 
class FirstClass extends Application {}
class SecondClass extends Application {}
class ThirdClass extends Application {}

And the rest of your code may program to the Application interface:

public void doSomethingWith( Application application ) {
        System.out.println( application.toString() );
}
public void startApplication( Application app ) {
    // etc etc 
}

Whenever you need a new instance you just call:

Application newApp = original.newInstance();

And that would create the correct type.

As you see the subclasses doesn't specify how to create new subclasses, that's all in the base class.

Invoking the method newInstance will always create a new instance which of the same type.

Sign up to request clarification or add additional context in comments.

2 Comments

Hmm... still smells of a horrible design bug to me. Also, relies on every subclass having a no-args constructor.
That's probably because we have ... different exposure to software development. But to be honest, this idea is not my idea at all. It is described in the book: Design Patterns: Elements of Reusable Object-Oriented Software The main problem it solves, is specifying the factory at runtime ( when you don't know what types of objects you'll create )
6

If a superclass knows about its subclasses, this points to poor design.

The normal way of achieving something like this is to have a protected abstract method which subclasses must implement to return a subclass-specific result.

2 Comments

This. You probably want to use the template method pattern instead: en.wikipedia.org/wiki/Template_method_pattern
Is not the superclass knowing its subclasses but letting the factory be specified at runtime. Like in the prototype design pattern.
1

I'm a bit rusty on my Java, but I believe that reflectively code executing in the super-class (in this example class A) will think it's part of the subclass.

Example:

public abstract class A
{
   public abstract void Something();
   public A Create()
   {
       Class me = this.getType(); // Returns a Reflective "Class" object for the SUB-Type
       // Use this object to reflectively instantiate a new instance, cast it as an A
       object obj = ReflectiveInstantiationHere(ItsBeenAWhile, SoGoogleThisPlease);

       return (A)obj;
   }
}

public class B extends A
{
   public void Something() 
   {
      A newInstanceOfB = Create();
   }
}

You can cast the returned value from A into a B later after checking types of course :)

Comments

1

Something like this?

 abstract class Abs{
    public <T extends Abs> T getInstance(Class<T> clazz) throws InstantiationException, IllegalAccessException {
        return clazz.newInstance();
    }
 }

Though this does not guarantee you'll get an instance of the class you're calling it from. To do that you'd still have to do something like:

class Abs1 extends Abs {
    public Abs1 getInstance() { return super.getInstance(Abs1.class) }
}

so not much of an improvement there.

I think the conclusion here is you'll end up with a lot less code and a lot less headaches if you just declare the method abstract in the parent, and implement it with new WhateverClassImIn() in every class that extends it. You can (probably) do it the way you want to, but it's not gonna be worth the effort.

Comments

0

You can do it, but only with hackery. I'm sure other people will give details.

It's a bit of an odd design. You shouldn't really care about specific implementations - stick to the interfaces. The best you can do without changing the design much is:

protected abstract A createCompatibleInstance();

Have subclasses implement it.

But yuck.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.