基于派生数据实施子类行为

时间:2012-12-30 17:19:22

标签: java inheritance

我正在尝试实现一个“Range”类(在Java中),为它包装的int值提供边界强制功能。我希望每个子类都定义自己的最小/最大边界,而不必重写强制执行这些边界的逻辑。这是一个例子:

public abstract class Range {
    // I would like each derived class to possess its own distinct instances of the
    // min/max member data
    protected static final int MIN_VAL;
    protected static final int MAX_VAL;

    protected int _value;

    public void set (int newVal) {
        // Range check the input parameter
        // this should use the min/max bounds for the object's most derived class
        if (newVal < MIN_VAL || newVal > MAX_VAL) {
            throw new InvalidParameterException("`newVal` is out of range");
        }

        this._value = newVal;
    }

    public int get() {
        return this._value;
    }
}

// This class should limit its wrapped value to values between 1 and 6 inclusively
public class Die extends Range {
    public Die() {
        MIN_VAL = 1;
        MAX_VAL = 6;
        this.set (1);
    }
}

显然这个实现不起作用,但我怎样才能实现目标?这可能不重复很多逻辑吗?

2 个答案:

答案 0 :(得分:3)

一种方法是制作最小/最大值实例变量,并让子类在构造函数中设置范围:

public abstract class Range {
    // I would like each derived class to possess its own distinct instances of the
    // min/max member data
    protected final int MIN_VAL;
    protected final int MAX_VAL;

    protected int _value;

    protected Range(int min, int max) {
        MIN_VAL = min;
        MAX_VAL = max;
    }

    . . .
}

// This class should limit its wrapped value to values between 1 and 6 inclusively
public class Die extends Range {
    public Die() {
        super(1, 6);
        . . .
    }
}

另一种方法是定义抽象的checkRange方法:

public abstract class Range {
    protected int _value;

    public void set (int newVal) {
        checkRange(newVal);
        this._value = newVal;
    }

    public int get() {
        return this._value;
    }

    protected abstract void checkRange(int val) throws InvalidParameterException;
}

// This class should limit its wrapped value to values between 1 and 6 inclusively
public class Die extends Range {
    private final int MIN_VAL = 1;
    private final int MAX_VAL = 6;
    public Die() {
        this.set (1);
    }

    protected void checkRange(int val) throws InvalidParamterException {
        if (newVal < MIN_VAL || newVal > MAX_VAL) {
            throw new InvalidParameterException("`val` is out of range");
        }
    }
}

答案 1 :(得分:1)

MIN_VAL和MAX_VAL是常量,因此您无法更改它们。

添加两个受保护的方法:

protected abstract int getMin();

protected abstract int getMax();

子类实现这些方法,例如:

@Override
protected int getMin() {
   return 7;
}

@Override
protected int getMax() {
   return 67;
}

在范围内,然后更改

public void set (int newVal) {
        // Range check the input parameter
        // this should use the min/max bounds for the object's most derived class
        if (newVal < getMin() || newVal > getMax()) {
            throw new InvalidParameterException("`newVal` is out of range");
        }

        this._value = newVal;
    }