0

提前感谢您的阅读。

我所说的“重新定义”是广泛使用的UML规范中的概念。

我的理解是: “重新定义”属性的类型是“重新定义”属性类型的子类。而“重新定义”属性的所有者是“重新定义”属性的所有者的子类。

给出以下示例:

Duration extends ValueSpecification
DurationInterval extends Interval
Interval has two attributes typed by ValueSpecification, min and max;
DurationInterval has two "redefined" attributes typed by Duration, min and max;

这是我的实现:

1) 如果我在 DurationInterval 中定义 min/max,我将隐藏另一个字段;实际上,这是实现“重新定义”属性的最简单方法。有人投票支持这种实施吗?

public Duration min/max;

2)然后我介绍了“Getter”,太好了,Oracle描述了“协变返回类型”,所以这种方式有效。但是,我必须向下转换类型才能使其工作。

3) 但是,对于“Setters”,如果我添加“@Override”,我会得到错误。我认为这是有争议的;首先,我必须承认甲骨文明确表示这不是覆盖。其次,我认为它是“覆盖”,只是 Oracle 还没有实现它。我错了,因为我不知道他们这样做的原因吗?

4)你对UML的重新定义属性的实现是什么?

public class RedefineProj {
    static class ValueSpecification{}
    static class Duration extends ValueSpecification{}
    static class Interval{
        public ValueSpecification min;
        public ValueSpecification max;

        public ValueSpecification getMin(){
            return min;
        }
        public ValueSpecification getMax(){
            return max;
        }
        public void setMin(ValueSpecification min_){
            min = min_;
        }
        public void setMax(ValueSpecification max_){
            max = max_;
        }
    }
    static class DurationInterval extends Interval{
        @Override
        public Duration getMin(){
            return (Duration) min;
        }
        @Override
        public Duration getMax(){
            return (Duration)max;
        }
        public void setMin(Duration min_){
            min = min_;
        }
        public void setMax(Duration max_){
            max = max_;
        }
    }

    public static void main(String[] args) {
        // TODO code application logic here
        Interval i = new Interval();
        ValueSpecification v = i.getMax();

        DurationInterval di = new DurationInterval();
        Duration d = di.getMax();
    }
}
4

1 回答 1

0

最简单的方法是像在第一点中那样重新定义属性。

protected Duration min;
protected Duration max;

这样,您将隐藏父类定义的属性。由于这不是真正的重新定义,因此您必须做更多的工作才能强制执行它们的类型。必须更改 setter 方法才能仅接受Duration对象。你可以这样做:

@Override
public void setMin(ValueSpecification min_)
{
    min = (min_ instanceof Duration) ? min_ : min;
}

@Override
public void setMax(ValueSpecification max_)
{
     max = (max_ instanceof Duration) ? max_ : max;
}

您的新 setter 方法不覆盖 fromInterval的原因是因为它们具有不同的参数,因此被视为单独的方法(这个概念称为重载)。在您的代码中,原始的 setter-methods 仍然可以在来自DurationInterval. 另一方面,上面的代码覆盖了父方法并修改了它们,以便只接受 Duration 输入(其他的被忽略;如果你愿意,你可以抛出一个异常)。

附带说明:您不应该将属性定义为,public因为所有对象都可以直接访问它们并且可以将它们置于无效状态(例如 null、否定等)。始终使用,private或者如果您希望它们可以在子类中使用protected.

于 2013-05-31T03:16:32.720 回答