Java的“self”关键字是什么?

10

我正在尝试在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这样的关键字吗,我可以用它来做这件事吗?

4个回答

9
在Java中,静态方法的继承方式与非静态方法不同。子类将拥有其父类的静态方法,但当它们执行时,它们将在超类的上下文中执行 - 因此,在静态方法中没有关键字可以用于查找调用该方法的类。

编辑:更精确的表述是静态方法根本不会被继承;然而,语言允许我们使用 Subclass.foo()来调用静态方法 Superclass.foo()

根据您似乎想要实现的内容,您可能需要实现抽象工厂模式。 大致如下:

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)。


@Ross:也许吧 - 你需要在什么情况下创建实例(为什么你需要那个方法而不是直接使用子类构造函数)?你是否需要在事先不知道需要哪种类的情况下创建实例?如果是这样,请参阅有关抽象工厂模式的代码示例的更新;否则,该模式可能过于复杂了。 :-) - Aasmund Eldhuset
我理解整个重点在于使事物具有动态性。 - vbence
@tada:请解释一下,我在哪里自相矛盾了?(我建议使用抽象工厂模式,因为我认为他想要实现的就是这个,但后来我意识到也许他有其他意图,所以我只是想明确指出该模式仅在某些情况下有用。或者你在考虑其他事情吗?) - Aasmund Eldhuset
@tada:啊,我想你是指我对包含编译错误答案的负投票;我现在已经修复了错误(至少我能发现的那一个)。 - Aasmund Eldhuset

3
如果你非常需要的话,你可以在静态上下文中使用以下代码:
Class cls = new Object() { }.getClass().getEnclosingClass();
Object instance = cls.newInstance();

您的类需要有一个无参构造函数。


2
你需要一些技巧才能实现这个目标。我想到的一种方法是:

你需要一些技巧才能实现这个目标。我想到的一种方法是:

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

0

我认为在Java中不可能找到“当前”子类的名称,特别是一些动态对象生成也不可能。

因此,您需要在每个子类中定义该静态函数。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接