[英]Creating an instance of a subclass extending an abstract class (Java)
在Java中,有沒有辦法在類A的成員方法中創建擴展抽象類A的任何類的實例? 擴展抽象類A的類將使用此方法返回其實例,但我不想在所有子類中使用“return this();”實現相同的方法。 親切的。
編輯:對不起,簡短的解釋。 在我的應用程序中,有一個名為Application的接口,它有一個返回Application類型的getInstance()方法。 有一個名為AbstractApplication的抽象類,它是Application接口實現的便利類,但只有接口在其他應用程序中公開。 在其他一些應用程序中,將會查找應用程序對象,此查找將返回應用程序類型(接口),而不是特定的實現。 現在這是我的問題; 有沒有辦法在AbstractApplication類中實現getInstance(),所以子類不需要實現這個方法?
葉氏。 這很容易(除非我誤解)
你必須使用原型設計模式(或我在這里展示的變體)
當您在運行時之前不知道工廠類可能是什么時,它很有用。 與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
方法將始終創建一個相同類型的新實例。
如果一個超類知道它的子類,這就指出了糟糕的設計。
實現這種目標的常規方法是使用受保護的抽象方法,子類必須實現該方法以返回特定於子類的結果。
像這樣的東西?
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()
實現它,那么你最終會得到更少的代碼和更少的麻煩。 你可以(可能)以你想要的方式去做,但這不值得付出努力。
我的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.
你可以做到,但只有hackery。 我相信其他人會詳細說明。
這有點奇怪的設計。 你不應該真正關心具體的實現 - 堅持接口。 在不改變設計的情況下,您可以做的最好的事情是:
protected abstract A createCompatibleInstance();
讓子類實現它。
但是你好。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.