我正在尝试设计一个抽象类,它将强制实现一个实例变量,即使这个实例变量的类型在抽象级别是未知的。例如:
public abstract class AbstractDiet{
abstract void computeMeat()
abstract void computeVeggies()
…
}
public abstract class AbstractAnimal{
protected AbstractDiet diet;
…
}
然后我希望用户实现类似:
public class Cat extends AbstractAnimal{
protected CatFoodDiet diet; // CatFoodDiet extends AbstractDiet
…
}
这是实现diet
变量的最佳方式吗?我想ENFORCE,AbstractDiet的子类总是在AbstractAnimal的子类中实现。
答案 0 :(得分:1)
你不能(也不应该)接近这样的设计。使用抽象类,尝试这样的事情:
public abstract class AbstractDiet {
abstract void compute();
}
public abstract class AbstractAnimal<T extends AbstractDiet> {
protected T diet;
}
public class CatFoodDiet extends AbstractDiet {
compute() {
//
}
}
public class Cat extends AbstractAnimal<CatFoodDiet> {
// use field in super which is type CatFoodDiet
}
但通常你会为抽象类型使用接口而不是抽象类。
答案 1 :(得分:1)
首先:保持实例变量的私有性,并提供访问器方法。
其次:听起来你正试图定义一个界面。每次想要说出类似的东西时都要使用界面,&#34;每个动物都有节食。&#34;
interface Animal {
Diet getDiet();
...
}
如果您愿意,还可以加入波希米亚的想法,并使其成为通用的。
interface Animal<D extends Diet> {
D getDiet();
...
}
这样,在定义不同种类的动物时,你将获得最大的自由
class Cat implements Animal<CatDiet> {
CatDiet getDiet() { return...; }
}
答案 2 :(得分:1)
最灵活的方法是只需要子类提供信息:
public abstract class AbstractAnimal {
// Subclasses must provide a function that returns the diet
public abstract AbstractDiet getDiet();
}
public class PetRock extends AbstractAnimal {
@Override
public AbstractDiet getDiet() {
return new SunlightDiet();
}
}
如果您想强制执行特定的实现,这是一种常见的方式:
public abstract class AbstractAnimal {
private AbstractDiet diet;
// Provide a constructor that sets a diet
protected AbstractAnimal(AbstractDiet aDiet) {
if (null == aDiet)
throw new NullPointerException("Diet must be specified");
diet = aDiet;
}
public class PetRock extends AbstractAnimal {
public PetRock() {
// Subclasses have to provide a diet to the superclass
super(new SunlightDiet());
}
}