Question

Thank you in advance for reading.

The "redefined" I'm talking about is the concept in UML Specification which is widely used.

My understanding is that: a "redefined" attribute's type is the subclass of the "redefining" attribute's type. While the owner of "redefined" attribute is the subclass of the owner of "redefining" attribute.

Given following example:

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;

Here is my implementation:

1) If I define min/max in DurationInterval, I'm hiding another field; Actually, this is the easiest way to implement a "redefined" attribute. Anyone vote for this kind of implementation?

public Duration min/max;

2) Then I introduced the "Getter", great, the Oracle described "covariant return type" so this way works. However, I have to cast the type downward to make it work.

3) For the "Setters" however, if I add "@Override", I will get error. I think this is arguable; Firstly, I have to admit that Oracle said explicitly that this is not override. Secondly, I think it is "Override" just Oracle didn't implement it yet. Am I wrong because I don't know the reason they do in this way?

4) What's your implementation on UML's Re-defined attribute?

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();
    }
}
Was it helpful?

Solution

The simplest way is to redefine the attributes like you do in your first point.

protected Duration min;
protected Duration max;

In this way you would hide the attributes defined by the parent class. Since this is not a real redefnitiion you have to do more work in order to enforce their type. The setter methods have to be changed in order to only accept Duration objects. You can do this like this:

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

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

The reason why your new setter-methods do not override the ones from Interval is because they have different parameters and are therefore treated as individual methods (the concept is called overloading). In your code the original setter-methods would still be callable on objects from DurationInterval. The above code on the other hand overrides the parent method and modifies them in order to only accept Duration inputs (others are just ignored; if you want you can throw an Exception instead).

As a side note: You should not define the attributes as public because all object would have direct access to them and can put them in invalid states (e.g. null, negative, etc). Always go with private or if you want them to be accessible in child classes with protected.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top