从Java中的抽象类强制实例变量实现

时间:2014-04-08 20:44:24

标签: java inheritance abstract-class

我正在尝试设计一个抽象类,它将强制实现一个实例变量,即使这个实例变量的类型在抽象级别是未知的。例如:

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的子类中实现。

3 个答案:

答案 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());
    }
}