Проблема наследования Java: выход за пределы vtable - PullRequest
2 голосов
/ 13 апреля 2011

Вот сценарий: у меня есть интерфейс A, 100 классов B0 ... B99, которые реализуют только A и 50 классов C0, C2 ... C98, которые расширяют B0, B2 ... B98.

Классы B работают с базой данных MySQL, выполняя различные операции с таблицами. Классы C добавляют дополнительную логику к классам B (проверки, привилегии и т. Д.). Классы B генерируются инструментом, а классы C пишутся кодером.

Клиентское приложение будет использовать классы B и не будет иметь доступа к классам C. Когда метод вызывается для объекта B, клиент сериализует объект и отправляет его приложению сервера вместе с именем метода, который должен быть вызван.

Сервер получит объект B и преобразует его как A. Однако сервер хотел бы выполнить метод, который был переопределен в классе C, если такой класс существует, и метод из B в противном случае. Нормальное поведение будет выполнять метод только из B.

Как сервер сможет это сделать, не имея огромного оператора SWITCH, который приведёт полученный объект к C?

РЕДАКТИРОВАТЬ: Я новичок в Java и не знал, что может сделать отражение. С небольшой помощью Google ( это и это ) я решил свою проблему. Я могу использовать динамическое приведение для того, чего я хочу достичь. Спасибо всем.

Ответы [ 3 ]

2 голосов
/ 13 апреля 2011

Предполагая, что у каждого класса C есть конструктор или статический createFromSuper для его создания из родительского B (или из A) ...

Вы можете создать FactoryClass, в котором зарегистрированы все доступные C.Вы можете использовать отражение, чтобы получить родительский элемент C, который вы хотите «заменить», помня каждое отображение B.class-> C.class в Map / Hashtable.

Затем, когда вы получаете B, вы передаете егона фабрику, которая вернет тот же объект B, если найдет сопоставление, или вызовет конструктор / createFromSuper, возвращающий C.

2 голосов
/ 13 апреля 2011

Такой подход звучит очень странно для меня. Почему бы вам просто не предоставить команды (например, строки, которые определяют имена команд) и зарегистрировать объекты команд для этих команд? Затем вы просто отправляете команду и некоторые сериализованные параметры.

Edit:

Из вашего описания кажется, что объекты C действительно будут декораторами для объекта B. В этом случае они не будут наследовать от соответствующего B, а будут получать ссылку на него, и сервер затем будет искать декораторы для переданного B (например, на основе класса или любого другого идентификатора), создавать их (или только один) передавая B, а затем вызвать метод на декоратор.

Очень похоже на BufferedReader украшение любого Reader.

1 голос
/ 13 апреля 2011

Хорошо, у вас есть объект типа времени выполнения B, и вы просите назвать его так, как если бы это был объект типа C. Это не совсем так, как работает наследование;вы не можете уменьшить до C, если он изначально не был создан как C, потому что в общем случае он не имеет всех полей C.

Я предполагаю, что ваши классы C не добавляют никаких дополнительных полей в B(если они это сделают, ваш вопрос не будет иметь смысла).Поскольку они не добавляют никаких дополнительных полей, я могу понять, как имеет смысл рассматривать их как C, но не очень хороший способ сделать это.Я бы сказал:

  1. Почему B и C в первую очередь?Почему бы просто не иметь классы B со всеми привилегиями и т. Д. И использовать их?
  2. Если это не удастся, я полагаю, вы могли бы использовать рефлексию.Напишите некоторый универсальный код, который принимает любой из ваших объектов класса B, создает новый соответствующий объект C и копирует все поля.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...