Изменение типа объекта во время выполнения

#java

#java

Вопрос:

У меня следующий сценарий:

 class Parent {}

class Child1 extends Parent {}

class Child2 extends Parent {}

interface ExternalSystem {
    Parent materialize(Parent a)
}

class Child1System implements ExternalSystem {
    Parent materialize(Parent a) {
        // specialize a and convert it into Child1
    }
}

class Child2System implements ExternalSystem {
    Parent materialize(Parent a) {
       //  specialize a and convert it into Child2
    }
}
  

Я хочу разрешить пользователям создавать объекты типа Parent . Некоторые компоненты системы согласны с предоставляемой информацией Parent . Однако в какой-то момент я хочу материализовать эти объекты во внешней системе, и в зависимости от того, какую ExternalSystem реализацию я вызываю, Parent объекты теперь должны быть специализированными объектами.

Есть ли способ создать новый дочерний объект и заменить пространство, используемое родительским объектом?

Я не могу просто заменить Parent a object на объект нового типа Child1 или Child1 потому что a на него могли ссылаться в других местах. Итак, по сути, я хочу, чтобы все ссылки продолжали просматриваться, Parent a но вместо того, чтобы a иметь тип Parent , теперь это будет дочерний тип.

В качестве альтернативы, это может быть разработано по-другому?

Комментарии:

1. Создайте конструктор в Child1 и Child2, который принимает экземпляр Parent и копирует информацию от parent к child, и используйте этот конструктор для возврата child в materialize() .

2. @Bala это не решает его требование о том, что ссылки на parent автоматически становятся ссылкой на Child1.

3. @MeBigFatGuy Я думал о чем-то вроде x = materialize(x);

4. @ivotron не может сделать то, что вы хотите. Изначально вам пришлось бы создать объекты Child1 или Child2. Вы всегда можете сохранить эти объекты в качестве родительского типа. таким образом, методы типа Child1 или Child2 недоступны, но их все равно нужно создать как Child1 или Child2.

5. @Bala, по-прежнему не работает, поскольку какой-то другой класс содержит ссылку на старый x, который не обновляется в вашем примере кода.

Ответ №1:

В Java нет функции размещения нового. По определению управляемой кучи.

Единственное, что вы можете сделать, это создать прокси-объект, который реализует ExternalSystem. Этот прокси-сервер будет отправлять вызовы экземплярам child1 или child2.

Комментарии:

1. Ах, прокси! да, это сработало бы — хорошая мысль. java.lang.reflect.Proxy

Ответ №2:

Есть ли способ создать новый дочерний объект и заменить пространство, используемое родительским объектом?

Способа нет. Тип объекта не меняется в течение срока службы объекта. Данная ссылка всегда указывает на один и тот же объект.

Вы можете использовать какой-либо механизм прокси или делегирования и заставить прокси / делегат ссылаться на разные вещи в течение своего срока службы. Тип объекта прокси / делегата не изменится, но он будет вести себя как экземпляр одного из дочерних типов … во многих отношениях. (Одна вещь, которая не будет работать … конечно… будет instanceof оператором.)