2011-05-26 45 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(); 

你的类必须有一个无参构造函数。