创建扩展抽象类的子类的实例(Java)

时间:2010-06-08 21:35:21

标签: java oop

在Java中,有没有办法在类A的成员方法中创建扩展抽象类A的任何类的实例?扩展抽象类A的类将使用此方法返回其实例,但我不想在所有子类中使用“return this();”实现相同的方法。亲切的。

编辑:很抱歉这个简短的解释。在我的应用程序中,有一个名为Application的接口,它有一个返回Application类型的getInstance()方法。有一个名为AbstractApplication的抽象类,它是Application接口实现的便利类,但只有接口在其他应用程序中公开。在其他一些应用程序中,将会查找应用程序对象,此查找将返回应用程序类型(接口),而不是特定的实现。现在这是我的问题;有没有办法在AbstractApplication类中实现getInstance(),所以子类不需要实现这个方法?

5 个答案:

答案 0 :(得分:9)

叶氏。这很容易(除非我误解)

你必须使用原型设计模式(或我在这里展示的变体)

当您在运行时之前不知道工厂类可能是什么时,它很有用。与AbstractFactory不同,您可以在其中创建新类型的不同子类,但您可以根据特定条件选择一个。

使用原型,您可以简单地将“原始”对象(原型)注入到您的应用程序中(通过完整的未来依赖注入框架或简单的类名称),然后创建它的新实例。

以下示例代码显示了如何使用变体执行此操作(不使用clonenewInstance方法)

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 {}

其余代码可以编程到Application界面:

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

每当您需要新实例时,只需致电:

Application newApp = original.newInstance();

这将创建正确的类型。

如您所见,子类未指定如何创建新的子类,这些都在基类中。

调用方法newInstance将始终创建一个相同类型的新实例。

答案 1 :(得分:6)

如果超类知道它的子类,则表明设计不佳。

实现类似这样的事情的正常方法是拥有一个受保护的抽象方法,子类必须实现该方法以返回特定于子类的结果。

答案 2 :(得分:1)

这样的东西?

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

虽然这并不能保证你会得到一个你正在调用它的类的实例。要做到这一点,你仍然需要做类似的事情:

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

因此没有那么大的改进。

我认为这里的结论是,如果您只是在父级中声明方法abstract,并且在扩展它的每个类中使用new WhateverClassImIn()实现它,那么您最终会得到更少的代码和更少的麻烦。 。你可以(可能)以你想要的方式去做,但这不值得付出努力。

答案 3 :(得分:1)

我的Java有点生疏,但我相信在超类中执行的反射代码(在本例A中)会认为它是子类的一部分。

示例:

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();
   }
}

您可以在检查课程类型之后将返回的值从A转换为B:)

答案 4 :(得分:0)

你可以做到,但只能用hackery。我相信其他人会提供详细信息。

这有点奇怪的设计。你不应该真正关心具体的实现 - 坚持接口。在不改变设计的情况下,您可以做的最好的事情是:

protected abstract A createCompatibleInstance();

让子类实现它。

但是你好。