Какой способ лучше? Понижающее приведение? Интерфейс? Абстрактный класс?
Все,
Я должен делать это неправильно. В то время это казалось хорошей идеей, но когда я углубился в нее, я думаю, что есть более правильный программный способ решения этой проблемы. Таким образом, я прошу вас...
Одна запись. Я использую Google AppEngine и хранилище данных для хранения этой информации.
Хорошо... допустим, у меня есть суперкласс транспортного средства, в котором есть 3 подкласса: легковой автомобиль, грузовик, мотоцикл.
В Super Class есть 3 свойства... Производитель, Модель, Тип
Например, это могут быть:
- Производитель: Форд
- Модель: Фокус
- Тип: Автомобиль
Итак, в Datastore у меня есть множество сущностей Vehicle с этими свойствами. Так что, если пользователь хочет видеть все машины... Я потяну все с типом "Автомобиль".
Если пользователь затем хочет добавить один из этих транспортных средств в список "Избранное", я затем преобразую объект "Автомобиль" в его конкретный подкласс в зависимости от его типа. Затем это добавляет дополнительные свойства этого конкретного подкласса.
Этот новый дочерний объект хранится в хранилище данных с его добавленными свойствами.
Так что, в основном, я преуменьшаю значение, например, от Автомобиля до Автомобиля. Я сделал это, создав дополнительный конструктор в классе Car, который принимает Vehicle в качестве аргумента. После создания объект Car теперь имеет все установленные свойства (Производитель, Модель, Тип) и все новые свойства, которые входят в его конкретную реализацию.
Это просто кажется запутанным и неправильным. Это работает, но должен быть лучший способ сделать это.
Основная причина, по которой я выбрал этот способ, заключается в том, как работает хранилище данных GAE. Это "дешевле" хранить Super Class и его ограниченные свойства и запрашивать их. Длинная история.
Я пытаюсь обернуть голову, используя интерфейсы и / или абстрактные классы для этого, но я хотел получить весь ваш вклад.
Спасибо за помощь.
2 ответа
Я не думаю, что вы хотите структуру супер / подкласса здесь. Ваша описанная проблема заключается в том, что вы "меняете" объект с одного типа на другой, и вы не можете изменить тип объекта Java. Вы можете создать новый объект, но затем вам придется перемещать всю свою информацию от одного к другому, и обслуживание становится проблемой.
Я полагаю, что у вас есть класс, который представляет ваш автомобиль, и что он содержит ссылку на информацию о конкретном типе; все классы, представляющие каждый конкретный тип, могут что-то расширять, и, вероятно, должны, чтобы методы в транспортном средстве, пытающиеся что-то сделать с типом, могли вызывать общий метод, чтобы сделать это независимо от типа. Но таким образом, как только вы определитесь с конкретным типом, вы можете добавить его к существующему объекту транспортного средства вместо того, чтобы "менять" его.
Вы также можете исследовать, будет ли перечислимый тип служить вашей цели для данных, специфичных для типа - типы enum могут принимать конструкторы, иметь дополнительные методы и т. Д. - учебник Oracle/Java по перечислениям охватывает это довольно хорошо.
Тип транспортного средства кодируется дважды: один раз как тип объекта и один раз как свойство. Избавьтесь от одного из них, чтобы не было возможности иметь Грузовик (тип объекта) со значением свойства Car. Сохраняйте структуру объекта или свойство, указывая тип транспортного средства (я рекомендую использовать Enum), но не оба.
Чтобы снизить рейтинг, вам не нужно создавать новый объект дочернего типа. Просто удрученный:
Car myCar = (vehicle instanceof Car ? (Car)vehicle : null);