简体   繁体   English

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

[英]Enforcing instance variable implementation from an abstract class in Java

I am trying to design an abstract class which will enforce implementation of an instance variable even though the type if this instance variable is unknown at the abstract level. 我正在尝试设计一个抽象类,该类将强制实例变量的实现,即使该实例变量在抽象级别是未知的也是如此。 For example: 例如:

public abstract class AbstractDiet{
    abstract void computeMeat()
    abstract void computeVeggies()
    …
}

public abstract class AbstractAnimal{
    protected AbstractDiet diet;
    …   
}

Then I'd like users to implement something like: 然后,我希望用户实现以下内容:

public class Cat extends AbstractAnimal{
    protected CatFoodDiet diet;   // CatFoodDiet extends AbstractDiet
    …
}

Is this the best way to implement the diet variable? 这是实现diet变量的最佳方法吗? I want to ENFORCE that a subclass of AbstractDiet is always implemented in a subclass of AbstractAnimal. 我想强制说AbstractDiet的子类总是在AbstractAnimal的子类中实现。

You can't (and shouldn't) approach the design like that. 您不能(也不应该)那样进行设计。 Using abstract classes, try something like this: 使用抽象类,尝试如下操作:

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
}

But typically you would use interfaces instead of abstract classes for the abstract types. 但是通常,对于抽象类型,您将使用接口而不是抽象类。

First of all: Keep your instance variables private, and provide accessor methods. 首先:将实例变量设为私有,并提供访问器方法。

Second of all: It sounds like you are trying to define an interface. 第二:听起来好像您正在尝试定义一个接口。 Use an interface any time you want to say something like, "every animal has a diet." 每当您想说“每只动物都有饮食”之类的内容时,都可以使用界面。

interface Animal {
    Diet getDiet();
    ...
 }

If you like, you can also incorporate Bohemian's idea, and make it generic. 如果愿意,您还可以合并Bohemian的想法,并使之通用。

interface Animal<D extends Diet> {
    D getDiet();
    ...
}

That way, you will have maximum freedom when it comes time to define different kinds of animal 这样,在定义不同种类的动物时,您将拥有最大的自由度

class Cat implements Animal<CatDiet> {
    CatDiet getDiet() { return...; }
}

The most flexible way is to just require the subclass to provide the information: 最灵活的方法是只要求子类提供信息:

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

If you want to force a particular implementation, this is a common way: 如果要强制执行特定的实现,这是一种常见的方法:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM