Ограничение типа ограниченного подстановочного знака в Java только одним уровнем подклассов класса?

Я хотел бы ограничить совместимые типы ввода метода набором определенных подклассов классов. Однако я хотел бы разрешить принятие только первого уровня подклассов. Например, класс «форма» имеет множество подклассов, например. «прямоугольник», «круг», «треугольник». Теперь у «прямоугольника» есть собственный подкласс «квадрат», так как же мне ограничить принятые коллекции, чтобы они принимали только иерархический уровень подклассов, состоящий из прямоугольника, круга и треугольника, не принимая квадрат?

0                 shape
                /   |   \
1       rectangle circle triangle
            |
2       square

Я знаю, что для охвата всех подклассов формы и их подклассов я бы сделал следующее:

public void methodName(List<? extends shape>){ ... }

Однако как бы я ограничил его только одним уровнем подклассов ниже формы? то есть ( только прямоугольник, круг, треугольник )


person Delrog    schedule 24.02.2016    source источник
comment
Краткий ответ: вы не можете. Длинный ответ: вы не можете, и вы не должны.   -  person Louis Wasserman    schedule 24.02.2016
comment
Если вы обнаружите, что вам это нужно, вам нужно сделать шаг назад и спросить себя, действительно ли наследование является правильным способом моделирования вашей проблемы. Это относится не только к дженерикам, но и к наследованию в целом. Просто потому, что в исходной задаче каждый A является B, это не обязательно означает, что класс, представляющий A, должен расширять класс, представляющий B.   -  person biziclop    schedule 24.02.2016


Ответы (1)


Если вы пытаетесь это сделать, значит, вы нарушаете принцип подстановки Лисков.

Короче говоря, в нем говорится, что подклассы всегда должны приниматься вместо их суперкласса. Концептуально, если квадрат является прямоугольником, то как может быть, что он не принимается, когда прямоугольник.

Итак, все это просто означает, что вы, вероятно, хотите смоделировать свою проблему по-другому. К сожалению, вы не упомянули, какое свойство имеет квадрат, что делает его каким-то образом не прямоугольником.

При этом сделать square подклассом rectangle обычно проблематично. См.: https://en.wikipedia.org/wiki/Circle-ellipse_problem.

person Robert Bräutigam    schedule 25.02.2016