дочерний объект инициализирован к родителю - PullRequest
2 голосов
/ 08 марта 2012

B является подклассом класса A.

A * a = [[B alloc] init];
B * b = [[A alloc] init];

Что из этого недействительно и почему?

Когда я набрал это, я получил предупреждение за второе, но я не мог понять, что это значит. Он показал «Несовместимые типы указателей, инициализирующие« B * __strong »выражением типа« A * »». Также может кто-нибудь сказать мне, можно ли сделать второе выражение допустимым или нет, и как сделать то же самое.

Ответы [ 2 ]

3 голосов
/ 08 марта 2012

Если B является подклассом из A, его экземпляры могут использоваться везде, где могут использоваться экземпляры A.Обратное неверно.

Вот реальный пример использования классов Apple: рассмотрим NSArray и его подкласс NSMutableArray.Поскольку NSMutableArray является NSArray, допустимо следующее присвоение:

NSArray *myArray = [[NSMutableArray alloc] init];

Однако, поскольку NSArray не обязательно является NSMutableArray, следующее присвоение недействительно:

NSMutableArray *myArray = [[NSArray alloc] init];

РЕДАКТИРОВАТЬ С языковой точки зрения оба назначения действительны: код собирается для компиляции и может даже выполняться, если вы держитесь подальше от Bметоды, также не поддерживаемые A, благодаря механизму диспетчеризации динамических методов Objective C. Но компилятор больше не может проверять код, содержащий переменную, и сообщать вам о других потенциальных проблемах.

0 голосов
/ 08 марта 2012
A * a = [[B alloc] init];  // OK
B * b = [[A alloc] init];  // INCORRECT

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

Вторая строка неверна по той же причине: экземпляры A не обязательно являются экземплярами B, поэтому неправильно назначать указатель на экземпляр A на переменную типа B*. Более конкретно, во второй строке вы создаете экземпляр A напрямую, поэтому результирующий объект определенно не является экземпляром B.

Подумайте об этом так: правильно описать любой квадрат в виде прямоугольника, но неверно говорить без дополнительной информации, что прямоугольник - это квадрат.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...