在Java中,有没有办法在类A的成员方法中创建扩展抽象类A的任何类的实例?扩展抽象类A的类将使用此方法返回其实例,但我不想在所有子类中使用“return this();”实现相同的方法。亲切的。
编辑:很抱歉这个简短的解释。在我的应用程序中,有一个名为Application的接口,它有一个返回Application类型的getInstance()方法。有一个名为AbstractApplication的抽象类,它是Application接口实现的便利类,但只有接口在其他应用程序中公开。在其他一些应用程序中,将会查找应用程序对象,此查找将返回应用程序类型(接口),而不是特定的实现。现在这是我的问题;有没有办法在AbstractApplication类中实现getInstance(),所以子类不需要实现这个方法?答案 0 :(得分:9)
叶氏。这很容易(除非我误解)
你必须使用原型设计模式(或我在这里展示的变体)
当您在运行时之前不知道工厂类可能是什么时,它很有用。与AbstractFactory不同,您可以在其中创建新类型的不同子类,但您可以根据特定条件选择一个。
使用原型,您可以简单地将“原始”对象(原型)注入到您的应用程序中(通过完整的未来依赖注入框架或简单的类名称),然后创建它的新实例。
以下示例代码显示了如何使用变体执行此操作(不使用clone
但newInstance
方法)
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();
让子类实现它。
但是你好。