2013-10-01 3 views
2

Например, у меня есть эти классы:Возможно ли изменить тип класса объекта с другим классом?

  1. MyGradientButton.h/.м
  2. RedGradientButton.h/.м (наследуемый класс MyGradientButton с цветом фона красный)

Теперь у меня есть экземпляр объекта «buttonA», который имеет характеристики класса MyGradientButton. Однако возможно ли позже изменить класс «buttonA» на RedGradientButton и приобрести новые характеристики класса, которые превратят кнопку в красную?

Если возможно, дайте мне знать как. Спасибо

+0

Короткий ответ - это просто «НЕТ». –

ответ

3

Нет, вы не можете изменить тип класса после его создания. [1]

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

Общим примером такой формы является: [NSString stringWithString:s] против [NSMutableString stringWithString:s];.

Поскольку вы имеете дело с видом, часто проще просто определить внутренний тип и использовать композицию объекта. Таким образом, у вас не будет типа RedGradientButton, но вместо него будет MyGradientButton, который имеет (например) член characteristics. Затем вы можете создать несколько типов характеристик (если подклассификация действительно хорошая конструкция).


[1] Вы могли, но делать не ... если кто-то говорит вам, как это может быть достигнуто. Причина: это небезопасно, и один подход уходит. Хотя вы можете установить класс, который будет обновлять методы, это не изменит другие аспекты объекта. Очевидным случаем является то, что ваш объект не будет изменен или изменен, чтобы отразить любую разницу в макете участника, а это означает, что когда вы отправляете сообщение об объекте и он обращается к членам, присутствующим в подклассе, но не к суперклассу, реализация вашего метода будет читать или писать неверная память (это неопределенное поведение). Даже если он работает, или вы динамически доказали или сделали все возможное, чтобы обеспечить его безопасность, современные среды выполнения используют не-хрупкий объект ABI - память, требуемая базовыми классами, может свободно меняться от одной версии к другой. Такая конструкция открыта для других ошибок при изменении размера (утечки, память, на которую нельзя ссылаться, или память «инициализированное в типе-преобразование» на данные другого класса). Поэтому, даже если вы преодолели проблему размера выделения, вам все равно нужно будет разработать способ частичного освобождения и частичной инициализации вашего экземпляра таким образом, чтобы объект находился в удобном для использования состоянии - довольно сложно.

+1

Спасибо за ваш комментарий Джастин. – Zaldy

2

Акачемический ответ: «Да, вы можете». Более разумный ответ: «Нет, вы не должны этого делать, если не понимаете, что вы делаете, и поэтому можете оправдать себя, хорошо ли это так».

Если бы я тебя, то я бы обрешетка новый фабричный метод для RedGradientButtion как +(instancetype) redGradientButtonWithMyGradientButton:(MyGradientButton*)myGradientButton;

Этого метода может затем создание экземпляра нового объекта RedGradientButton и скопировать все соответствующее charachteristics из myGradientButton.Тогда, если вы думаете, что это хорошая идея, он может получить myGradientButtons 'superiew, удалить его из своего супервизора и добавить новый объект RedGradientButton вместо него. Конечно, это сделало бы все ссылки на myGradientButton для ссылки на неиспользуемый (но с ARC по-прежнему действительный) объект Button. Вам нужно будет их обновить.

Вы говорите, что RedGradientButton наследует от MyGradientButton. Это означает, что все классы, которые используют MyGradientButton, должны продолжать работать хорошо - как только ссылки были обновлены, конечно.

+0

Благодарим вас за комментарий Hermann. – Zaldy

+0

Добро пожаловать. –

Смежные вопросы