What is Java's 'self' keyword
I'm trying to write a factory method in an abstract class in Java (so I want it to return a new instance of the extending class, rather than the super-class).
In PHP I'd do this using the self
keyword:
abstract class Superclass {
public static functi开发者_如何学Con factory($arg) {
return new self($arg);
}
private function __construct($arg) {}
abstract public function doSomething() {}
}
Does Java have a keyword like self
I can use for this?
No; in Java, static methods are not inherited in the same way as non-static methods are. A subclass will have the static methods of its superclass, but when they execute, they will execute in context of the superclass - so there is no keyword that can be used in static methods to find out what class the method was invoked through.
Edit: A more precise formulation is that static methods are not inherited at all; however, the language allows us to use Subclass.foo()
to call the static method Superclass.foo()
.
Based on what you seem to want to achieve, you might want to implement the Abstract Factory pattern. It goes approximately like this:
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();
}
}
Now, you can e.g. create a method that takes an AbstractFactory
(which, in reality, will be either a FactoryA
or a FactoryB
). Calling Create()
on this object will produce either a SubclassA
or a SubclassB
.
Edit: Fixed compilation error (forgot to make the factories extend AbstractFactory
).
If you absolutely have to you can use this code form a static context:
Class cls = new Object() { }.getClass().getEnclosingClass();
Object instance = cls.newInstance();
Your class need to have a nullary constructor.
You need some hacks to achieve this. One way I can think of to obtain this is:
public static <T extends SuperClass> T factory(Class<T> clazz) {
return clazz.newInstance();
}
I don't think it is possible in Java to find out the name of the "current" subclass. And especially some dynamic object generation won't be possible.
So you'll need to define that static function in every subclass instead.
精彩评论