Каков наилучший способ реализации переопределенного атрибута в Java?
Заранее спасибо за чтение.
"Переопределенный", о котором я говорю, - это концепция в спецификации UML, которая широко используется.
Насколько я понимаю, тип "переопределенного" атрибута является подклассом типа "переопределенного" атрибута. В то время как владелец атрибута "redefined" является подклассом владельца атрибута "redefining".
Приведен следующий пример:
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) Однако для "Сеттеров", если я добавлю "@Override", я получу ошибку. Я думаю, что это спорно; Во-первых, я должен признать, что Oracle прямо сказал, что это не переопределение. Во-вторых, я думаю, что это "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();
}
}
1 ответ
Самый простой способ - переопределить атрибуты, как вы делаете в своем первом пункте.
protected Duration min;
protected Duration max;
Таким образом, вы бы скрыли атрибуты, определенные родительским классом. Поскольку это не настоящее переопределение, вам нужно проделать больше работы, чтобы обеспечить их тип. Методы установки должны быть изменены, чтобы принимать только 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;
}
Причина, по которой ваши новые методы установки не переопределяют те из Interval
потому что они имеют разные параметры и поэтому рассматриваются как отдельные методы (концепция называется перегрузкой). В вашем коде оригинальные методы setter будут по-прежнему вызываться для объектов из DurationInterval
, Приведенный выше код, с другой стороны, переопределяет родительский метод и модифицирует их, чтобы принимать только входы Duration (другие просто игнорируются; если вы хотите, вы можете вместо этого выдать Exception).
Как примечание: вы не должны определять атрибуты как public
потому что все объекты будут иметь прямой доступ к ним и могут перевести их в недопустимые состояния (например, ноль, минус и т. д.). Всегда идти с private
или если вы хотите, чтобы они были доступны в дочерних классах с protected
,