2011-05-26 86 views
9

我想在Java的抽象類中編寫工廠方法(所以我希望它返回擴展類的新實例,而不是超類)。什麼是Java的「自我」關鍵字

在PHP中我會做這個使用self關鍵字:

abstract class Superclass { 
    public static function factory($arg) { 
     return new self($arg); 
    } 

    private function __construct($arg) {} 

    abstract public function doSomething() {} 
} 

確實的Java有一個像self一個關鍵詞,我可以使用嗎?

回答

8

否;在Java中,靜態方法不像非靜態方法那樣繼承。一個子類將擁有其超類的靜態方法,但是當它們執行時,它們將在超類的上下文中執行 - 因此沒有可用於靜態方法的關鍵字來找出該方法被調用的類。

編輯:更精確的表述是靜態方法根本不會被繼承;但是,該語言允許我們使用Subclass.foo()來調用靜態方法Superclass.foo()

根據您似乎想要達到的目標,您可能需要實施Abstract Factory pattern。它大致是這樣的:

public abstract class Superclass {} 
public class SubclassA extends Superclass {} 
public class SubclassB extends Superclass {} 

public abstract class AbstractFactory { 
    public abstract Superclass Create(); 
} 

public class FactoryA extends AbstractFactory { 
    public Superclass Create() { 
     return new SubclassA(); 
    } 
} 

public class FactoryB extends AbstractFactory { 
    public Superclass Create() { 
     return new SubclassB(); 
    } 
} 

現在,你可以例如創建一個採用AbstractFactory(其實際上將是FactoryAFactoryB)的方法。在此對象上調用Create()將產生一個SubclassASubclassB

編輯:修正編譯錯誤(忘記使工廠擴展AbstractFactory)。

+0

@Ross:也許 - 在什麼情況下,你需要創建實例(爲什麼你需要這種方法,而不是直接使用子類構造函數)?你是否曾經需要在事先不知道需要什麼樣的課程的情況下創建實例?如果是這樣,請參閱關於Abstract Factory模式的代碼示例更新;否則,該模式可能是過度殺傷。 :-) – 2011-05-26 22:38:58

+0

我明白整個觀點就是讓事情變得動態。 – vbence 2011-05-26 22:39:36

+0

@tada:請解釋一下;我在哪裏與自己矛盾? (我建議抽象工廠模式,因爲這是我認爲他想達到的目標,但後來我意識到也許他有其他意圖,所以我只想說清楚,這種模式只在某些情況下有用。想着別的嗎?) – 2011-05-26 22:45:04

0

我認爲在Java中找不到「當前」子類的名稱是可能的。特別是一些動態的對象生成是不可能的。

因此,您需要在每個子類中定義該靜態函數。

2

你需要一些黑客來實現這一點。我能想到的一種方式來獲得這樣的:

public static <T extends SuperClass> T factory(Class<T> clazz) { 
    return clazz.newInstance(); 
} 
3

如果你絕對必須您可以使用此代碼形式的靜態背景:

Class cls = new Object() { }.getClass().getEnclosingClass(); 
Object instance = cls.newInstance(); 

你的類必須有一個無參構造函數。