簡體   English   中英

創建擴展抽象類的子類的實例(Java)

[英]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不同,您可以在其中創建新類型的不同子類,但您可以根據特定條件選擇一個。

使用原型,您可以簡單地將“原始”對象(原型)注入到您的應用程序中(通過完整的未來依賴注入框架或簡單的類名稱),然后創建它的新實例。

這是一個示例代碼,顯示如何使用變體(不使用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方法將始終創建一個相同類型的新實例。

如果一個超類知道它的子類,這就指出了糟糕的設計。

實現這種目標的常規方法是使用受保護的抽象方法,子類必須實現該方法以返回特定於子類的結果。

像這樣的東西?

 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM