Лучшая практика для определения полей экземпляра суперкласса на основе подкласса

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

Должен ли я использовать для этого прямые ссылки field = value или использовать методы набора суперклассов setField(value);?

Я бы предпочел оставить поля закрытыми, поэтому я хочу избежать прямых ссылок.

Другой альтернативой является вызов суперконструктора, который позволит мне использовать прямые ссылки в конструкторе суперкласса super (T value) и в суперклассе SuperClass(T value){ field = value}. Будет ли это лучшим способом? Я мог бы даже использовать методы set внутри суперконструктора, но это кажется излишним.


person zephos2014    schedule 17.09.2014    source источник
comment
Вероятно, вам следует пересмотреть иерархию классов и посмотреть, есть ли в этом необходимость. Возможно, наследование создает для вас больше проблем, чем решает. Подклассы не должны иметь много одинаковых полей с разными значениями из суперкласса. Если вы не можете использовать какие-либо значения полей в суперабстрактном классе, зачем вы вообще их там определяете?   -  person M7Jacks    schedule 18.09.2014
comment
Потому что они общие для всех подклассов. Зачем объявлять их более одного раза? Я не объявляю их в подклассе.   -  person zephos2014    schedule 18.09.2014
comment
Почему бы тогда просто не определить поля в абстрактном суперклассе, но на самом деле не устанавливать для них какое-либо конкретное значение? Вы должны иметь возможность настроить свой абстрактный суперкласс таким образом, что если подкласс не устанавливает значение для какого-либо поля, создается исключение.   -  person M7Jacks    schedule 18.09.2014
comment
Это то, что я делаю. Я никогда не говорил, что инициализирую поля, кроме как через подкласс. Проблема в том, что поскольку они являются частными полями, доступ к ним должен осуществляться через суперконструктор или путем вызова общедоступных суперметодов. Я просто думал, какой способ лучше.   -  person zephos2014    schedule 18.09.2014


Ответы (2)


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

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

Всякий раз, когда вы хотите получить поля, вызовите «super.getValue (...)» и т. д.

person Ahmed Elmir    schedule 17.09.2014

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

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

person Kevin Krumwiede    schedule 17.09.2014
comment
Если поля имеют определенные ограничения, которые вы хотите применить с помощью абстрактного суперкласса, я понимаю вашу точку зрения на создание средств доступа и мутаторов. Однако, если это не так, может показаться, что zephos2014 может быть лучше просто использовать защищенные поля и обращаться к ним напрямую, поскольку он не указал причину, по которой он предпочитает закрытый доступ. - person M7Jacks; 18.09.2014
comment
Честно говоря, я просто следовал лучшим практикам. Если защищенный доступ не позволяет несвязанным классам изменять значения, это может работать нормально. - person zephos2014; 18.09.2014
comment
Если поля не имеют конкретных ограничений, то суперкласс просто действует как тупой контейнер для данных, за которые отвечает подкласс. Это требует композиции, а не наследования. Иерархии классов должны быть разработаны вокруг общих интерфейсов, а не общих данных. - person Kevin Krumwiede; 18.09.2014