关于oop:创建扩展抽象类的子类的实例(Java)

Creating an instance of a subclass extending an abstract class (Java)

在爪哇中,有没有一种方法可以在类A的成员方法中创建任何类来扩展抽象类A的实例呢?扩展抽象类A的类将使用此方法返回其实例,但我不希望在所有子类中使用"return this();"类行实现相同的方法。

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


耶普。这很容易(除非我误解了)

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

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

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

下面是一个示例代码,演示如何使用变体(不使用clone,而是使用newInstance方法)来完成此操作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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接口:

1
2
3
4
5
6
public void doSomethingWith( Application application ) {
        System.out.println( application.toString() );
}
public void startApplication( Application app ) {
    // etc etc
}

每当需要新实例时,只需调用:

1
Application newApp = original.newInstance();

这将创建正确的类型。

正如您所看到的,子类没有指定如何创建新的子类,这些都在基类中。

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


如果一个超类知道它的子类,这就意味着设计不好。

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


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

例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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:。


像这样?

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

尽管这不能保证您会得到一个从中调用它的类的实例。要做到这一点,你仍然需要做如下的事情:

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

所以那里没有多少改善。

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


你可以这样做,但只有黑客。我相信其他人会提供细节。

这是一个有点奇怪的设计。你不应该真正关心具体的实现——坚持使用接口。在不改变设计的情况下,最好的方法是:

1
protected abstract A createCompatibleInstance();

让子类实现它。

但是,哎呀。