Приведение программирования к реализации? - PullRequest
1 голос
/ 11 декабря 2011

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

Мне было интересно, было ли это нарушением программирования интерфейса?

Если это так, какой будет компромисс между реализацией пустого метода подкласса в суперклассе и переопределением его только в подклассе, который мне нужен? И если это сделает программирование на интерфейс?

Ответы [ 3 ]

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

..if this was a violation of programming to an interface?: Да, абсолютно.

Подробнее см. Принцип замещения Лискова .Это выглядит следующим образом:

Пусть q (x) - свойство, доказуемое для объектов x типа T. Тогда q (y) должно быть доказуемо для объектов y типа S, где S - подтипT.

Простое объяснение может быть что-то вроде:

Это должно быть возможно выполнить, ссылаясь на interface, что может быть сделано с помощью specific implementation.Если это невозможно, то это нарушает договор об использовании интерфейса.

Например, если что-то делается как

List<String> violating = new LinkedList<String>();
((LinkedList<String>)violating).addFirst("violating");

На самом деле нет смысла объявлять List<String> violating, как это необходимоиспользовать addFirst.Поэтому предпочтительно использовать LinkedList<String> violating здесь.Это должно ответить на остальное замешательство.

1 голос
/ 11 декабря 2011

Это как минимум кодовый запах.

Скажем, у вас есть class A и class B extends A, и у вас есть метод foo() в классе B. Теперь предположим, что у вас есть объект типа A, который может быть a B. Логически это означает, что в вашем контексте вам нужен объект типа A, независимо от супертипа. Так зачем вам звонить foo()? Если вам нужен вызов, почему бы не иметь объект B непосредственно в вашем контексте?

Я предлагаю вам поместить foo() метод только в A тогда и только тогда, когда имеет смысл, чтобы он был в A, а не так, вы можете просто переопределить его в B.

Полагаю, ваш дизайн ошибочен, но может и не быть. В этом случае вы можете использовать оператор instanceof, чтобы выяснить, относится ли ваш объект к типу B, после чего вы можете безопасно использовать его.

1 голос
/ 11 декабря 2011

Если метод не имеет смысла в суперклассе, добавлять его туда просто, чтобы избежать приведения, не очень хорошая идея.Если метод имеет смысл в суперклассе, и он не должен предпринимать никаких действий, тогда вы должны поместить метод в суперкласс и переопределить его в подклассе.Если функциональность добавленного метода вообще не принадлежит суперклассу, добавьте и реализуйте второй интерфейс в своем подклассе, и вместо этого запрограммируйте этот интерфейс, когда вам потребуется дополнительная функциональность.

Редактировать: вы можете добавитьинтерфейс WithText и добавьте его в подкласс, которому требуется setText.Если вы добавите больше подклассов, которым требуется setText, сделайте так, чтобы они также реализовали этот интерфейс.

interface Shape {
    void setPosition(int x, int y);
    void draw();
}
interface ShapeWithText : Shape {
    void setText(string text);
}
class Line implements Shape {
    // ...
}
class Circle implements Shape {
    // ...
}
class TextBox implements ShapeWithText {
    // ...
}
class CircularText implements ShapeWithText {
    // ...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...