Наследование - преобладающие методы мутатора? - PullRequest
2 голосов
/ 05 декабря 2011

Итак, допустим, у меня есть следующие классы:

Foo

abstract class Foo{
    .
    .
    .
    public void setKey(FooKey key){
        this.key = key;
    }
}

Bar

final class Bar extends Foo{
    .
    .
    .
    @Override
    public void setKey(BarKey key){ // Can't do this?
        super.setKey(key);
    }
}

В приведенном выше примере BarKey является подклассомFooKey.Здесь я хочу убедиться, что ключ, установленный для Bar, является определенным подклассом FooKey (то есть BarKey).Как мне это сделать?Я делаю это слишком сложным?Есть ли лучший дизайнерский подход?

Ответы [ 4 ]

4 голосов
/ 05 декабря 2011

Это не правильно, потому что вы делаете подкласс более строгим, чем суперкласс: суперкласс позволяет установить любой тип FooKey, но подкласс принимает только BarKey.

Для этого вам нужно сделать универсальный суперкласс:

abstract class Foo<K extends FooKey> {
    private K key;

    public void setKey(K key){
        this.key = key;
    }
}

final class Bar extends Foo<BarKey> {
}
2 голосов
/ 05 декабря 2011

Вы должны прочитать о разнице между переопределением и перегрузкой. То, что вы сделали, это просто перегрузили, потому что вы изменили тип аргумента, который не допускается с переопределением.

2 голосов
/ 05 декабря 2011

Вы не можете применить это таким образом. Рассмотрим:

Bar b = new Bar();
FooKey k = new FooKey();
b.setKey(k);  // You want to prohibit this
Foo f = b;
f.setKey(k);  // But there's no way to prohibit this

Как правило, производный класс не может предложить больше ограничительного интерфейса, чем его суперкласс.

Поэтому я бы предложил удалить setKey из абстрактного класса.

0 голосов
/ 05 декабря 2011

Просто удалите аннотацию @Override, так как вы не переопределяете метод суперкласса (должны быть те же аргументы), вы просто определяете новый метод setKey с более узким типом. Однако этот новый метод setKey будет доступен только через ссылку Bar.

...