Swift строго соблюдает класс в переменных протокола?

Для протокола P требуется переменная v класса C.

Класс X реализует протокол P, объявляя переменную v класса C1, где C1 расширяет C.

Вот код:

import Foundation    

class C { }
class C1: C { }

protocol P {
    var v: C { get set }
}

class X: P {
    var v: C1

    init(withV v: C1) {
        self.v = v
    }
}

Жалобы Xcode с этой ошибкой:

Type 'X' does not conform to protocol 'P'
Protocol requires property 'v' with type 'C'
Candidate has non-matching type 'C1'

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

Редактировать:

Точно такая же реализация в Obj-C компилируется без ошибок и предупреждений.

@interface C: NSObject
@end
@implementation C
@end

@interface C1: C
@end
@implementation C1
@end

@protocol P <NSObject>
    @property (nonatomic, strong) C *v;
@end

@interface X: NSObject <P>
    @property (nonatomic, strong) C1 *v;
@end
@implementation X
@end

person Scakko    schedule 08.04.2016    source источник


Ответы (1)


Это не заставляет вас точно соответствовать, но заставляет вас избегать проблем во время выполнения. Ваша установка может означать, что вы передаете ссылку на что-то, что утверждает, что соответствует P, но на самом деле не соответствует. Это потому, что P говорит, что вы можете установить v на любое C, а X говорит, что вы можете установить v на любое C1.

Итак, если вы создадите еще один подкласс C, C2 и попытаетесь использовать его, все развалится.

Я ожидаю, что ваш пример obj-c будет жаловаться на то, что вы не реализовали или не синтезировали свойство, указанное для существования в протоколе...

person Wain    schedule 08.04.2016
comment
Obj-C вообще не жалуется, но я только что понял, что набор в протоколе означает, что во время выполнения каждый может установить v в класс C, а X может не получить доступ к C, как если бы это был C1. Спасибо за ответ. - person Scakko; 08.04.2016