Creating an instance of a subclass extending an abstract class (Java)
在爪哇中,有没有一种方法可以在类A的成员方法中创建任何类来扩展抽象类A的实例呢?扩展抽象类A的类将使用此方法返回其实例,但我不希望在所有子类中使用"return this();"类行实现相同的方法。
编辑:好的,很抱歉有简短的解释。在我的应用程序中,有一个名为application的接口,它有一个getInstance()方法返回应用程序类型。有一个名为AbstractApplication的抽象类,它是一个方便应用程序接口实现的类,但只有该接口在其他应用程序中公开。在某些其他应用程序中,将查找应用程序对象,并且此查找将返回应用程序类型(接口),而不是特定的实现。现在我的问题是:有没有一种方法可以在AbstractApplication类中实现getInstance(),这样子类就不需要实现这个方法了?
耶普。这很容易(除非我误解了)
你必须使用原型设计模式(或者我在这里展示的它的变体)
当您在运行时之前不知道工厂类可能是什么时,它很有用。与AbstractFactory不同,AbstractFactory可以有不同的子类来创建新类型,但可以根据特定条件选择一个类型。
使用原型,您可以简单地将"原始"对象(原型)注入到应用程序中(通过一个完整的未来依赖项注入框架或一个简单的类名),然后创建它的新实例。
下面是一个示例代码,演示如何使用变体(不使用
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 {} |
其余代码可以编程到
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(); |
这将创建正确的类型。
正如您所看到的,子类没有指定如何创建新的子类,这些都在基类中。
调用方法
如果一个超类知道它的子类,这就意味着设计不好。
实现这种情况的正常方法是拥有一个受保护的抽象方法,子类必须实现该方法以返回子类特定的结果。
我对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) } } |
所以那里没有多少改善。
我认为这里的结论是,如果您只在父类中声明方法抽象,并在扩展它的每个类中使用
你可以这样做,但只有黑客。我相信其他人会提供细节。
这是一个有点奇怪的设计。你不应该真正关心具体的实现——坚持使用接口。在不改变设计的情况下,最好的方法是:
1 | protected abstract A createCompatibleInstance(); |
让子类实现它。
但是,哎呀。