【问题标题】:What is the best way to implement "redefined" attribute in Java?在 Java 中实现“重新定义”属性的最佳方法是什么?
【发布时间】:2013-05-31 02:37:32
【问题描述】:

提前感谢您的阅读。

我所说的“重新定义”是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 中定义最小值/最大值,我将隐藏另一个字段;实际上,这是实现“重新定义”属性的最简单方法。有人投票支持这种实现方式吗?

public Duration min/max;

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

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

4) 你对 UML 的 Re-defined 属性的实现是什么?

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

【问题讨论】:

  • 请遵守 Java 约定并以 小写字母 开头的方法名称,例如setMin(...)。大写字母用于类名。

标签: java attributes redefine


【解决方案1】:

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

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

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

【讨论】:

  • 接受您的所有意见。此外,如果传入的 min_/max_ 不是 instanceof Duration,则 min/max 保持其原始值或抛出异常是有争议的。引入具有显式参数类型的非覆盖设置器,因为“持续时间”也是候选者。不管怎样,再等 2 天,看看有没有更好的解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-19
  • 2020-11-26
  • 2011-08-07
  • 1970-01-01
相关资源
最近更新 更多