有很多方法可以做到这一点,假设你的意思是“创造我的孩子”。
反射
首先是使用反射。如果你有你的类无参数的构造,这是因为调用Class.newInstance一样容易:
public Animal breed() {
try {
return (Animal) getClass().newInstance();
} catch (Exception ex) {
// TODO Log me
return null;
}
}
如果你没有在所有的子类的无参数的构造函数,你必须有一个统一的构造函数遍历所有的子类。举例来说,如果你有Cat(int, String)
和Dog(int, String)
,那么你就需要通过Class.getConstructor
得到构造函数和调用上newInstance
:
return (Animal) getClass().getConstructor(int.class, String.class).newInstance(0, "Unnamed");
int
和String
这里可能是年龄和名字,例如。这就是你如何用反射来做到这一点。
提供商
另一种方法是使用这个简单的接口:
public interface Provider<T> {
T create();
}
然后让你的抽象类采取了这样的一个实例在其构造:
public abstract class Animal {
private final Provider<Animal> animalProvider;
protected Animal(... , Provider<Animal> animalProvider) {
// ...
this.animalProvider = animalProvider;
}
public Animal breed() {
return animalProvider.create();
}
}
然后你子类会将Provider<Animal>
传递给超类,它将创建子类的新实例:
public class Dog extends Animal {
public Dog(...) {
super(... , new DogProvider());
// ...
}
private static class DogProvider implements Provider<Animal> {
public Animal create() {
return new Dog(...);
}
}
}
对其他子类也做同样的事情。
注意:如果通过breed
您的意思是“得到我的类型”,那么你应该编辑你的问题说出来。如果这是你的意思,那么这是一个可行的解决方案:
public abstract class Animal {
protected final Breed breed;
protected Animal(... , Breed breed) {
// ...
this.breed = breed;
}
public Breed getBreed() {
return breed;
}
}
我建议您按照get
/set
约定数据容器的方法。 Java拥有旨在处理这些命名约定的bean类,它在很多平台上或多或少都是标准。为了您的子类:
public class Dog extends Animal {
public Dog(...) {
super(... , new Breed(...));
// ...
}
}
是的,它是没有必要的,在一个类中的所有方法都需要是抽象 –
@SashiKant虽然如此,我不认为这是OP是问什么...... –