2016-11-03 1 views
1

НапримерКак получить подкласс для переопределения родительского абстрактного метода с расширенным типом?

public abstract class ParentClass { 

    public abstract FooType getFoo(); 
    ... 
} 

, а затем что-то вроде

public abstract class SomeClass extends ParentClass { 

    public abstract SpecialFooType getFoo(); //clashes with the parent! 
    ... 
} 

В этом случае getFoo() из SomeClass должен быть FooType, который реализует интерфейс SpecialFooType. Однако я не знаю, как настроить синтаксис для этого.

+0

Расширяет ли 'SpecialFooType'' FooType'? – bradimus

+0

@bradimus № FooType - это просто его собственный класс. Но я хочу, чтобы у него были другие свойства, если вы получаете FooType из этого конкретного дочернего класса, которые определены в интерфейсе SpecialFooType. Другими словами, я хочу, чтобы getFoo() в дочернем классе возвращал то, что является как FooType, так и SpecialFooType. – KaliMa

+0

Вы не можете этого сделать, так как 'SpecialFooType getFoo()' и 'FooType getFoo()' будут отличаться только от типа возврата. У них будет такая же подпись. Вы могли бы это исправить, если «ParentClass» были родовыми. – bradimus

ответ

0

Inheritance is more, а не просто сдача расширяет в декларации определенного класса.

Например, ваши классы должны следовать за Liskov substitution principle. И этот принцип дает правила, как должно выглядеть переопределение методов.

Фактически это позволяет узким типам возвращаемых значений; например: базовый класс имеет Number getFoo(); и подкласс может делать Integer getFoo(). Но в вашем случае типы возврата: разные; поэтому ваша идея просто неверна на концептуальном уровне!

Обоснование этого. Если у вас есть клиентский код, который вызывает этот метод, то клиент должен не должен знать, вызывает ли он этот метод в базовом классе ... или какой-то подкласс. Другими словами: клиентский код должен иметь возможность обрабатывать ответ «Число», поэтому, конечно, он сможет иметь дело с возвратом целого. Теперь подумайте, как это должно работать в вашей настройке ... как сказано: это не так!

И только для полноты: LSP говорит, что возвращение типы могут быть сужены , в то время как параметры метода могут быть расширены. Поэтому, когда base foo() принимает Integer, подкласс foo() отлично подходит для Number.

+0

Я видел упоминание LSP много раз, но я просто не понимаю Wiki и я когда-либо видел ответ SO, который объясняет это легко, поэтому, к сожалению, это не принцип, который я знаю, как применять. – KaliMa

+0

Я только что обновил свой ответ. Если этого недостаточно, я могу дать еще несколько советов ... позже. Теперь прогуляйся по собаке ;-) – GhostCat

+0

Призрачная кошка идет собакой ... это было бы дико видеть. – KaliMa

Смежные вопросы