2016-05-19 3 views
11

Можно ли добавить соответствие протокола другому протоколу посредством расширения?Расширение существующих протоколов для реализации другого протокола с установками по умолчанию

Например, мы хотели бы, чтобы соответствовать B:

protocol A { 
    var a : UIView {get} 
} 

protocol B { 
    var b : UIView {get} 
} 

Я хочу дать реализацию по умолчанию (соблюдение) B к объектам типа А

// This isn't possible 
extension A : B { 
    var b : UIView { 
    return self.a 
    } 
} 

мотивация в том, чтобы повторно использовать объекты А в случаях, когда требуется В, без создания моего собственного «моста»

class MyClass { 
    func myFunc(object : A) { 
    ... 
    ... 
    let view = object.a 
    ... do something with view ... 

    myFunc(object)  // would like to use an 'A' without creating a 'B' 
    } 

    func myFunc2(object : B) { 
    ... 
    ... 
    let view = object.b 
    ... do something with view ... 

    } 
} 

Как примечание стороны, мы можем расширить класс для осуществления протокола

class C { 
    let C : UIView 
} 

// this will work 
extension C : B { 
    var B : UIView { 
    return self.c 
    } 
} 

и протоколы могут дать реализацию по умолчанию

extension A { 
    // a default implementation 
    var a : UIView { 
    return UIView() 
    } 
} 

ответ

3

Вы можете сделать Aнаследует от B:

protocol A: B { var a: String { get } } 
protocol B { var b: String { get } } 

// Default implementation of property b 
extension A { 
    var b: String { get { return "PropertyB" } } 
} 


class MyClass: A { 
    var a: String { get { return "PropertyA" } } 

    func printA(obj: A) { 
     print(obj.a) 
     printB(obj) 
    } 

    func printB(obj: B) { 
     print(obj.b) 
    } 
} 

let obj = MyClass() 
obj.printA(obj) 

С A наследует от B, каждое имущество в B доступен в A.

+4

Это в корне отличается от того просит ОП , Если у него нет контроля над «А» или «В», это не поможет. –

+0

Тогда, я полагаю, вы можете сделать протокол 'C', который реализует как' A', так и 'B', при необходимости по умолчанию? –

+1

Я не хочу создавать дополнительные протоколы. –

8

При расширении A, можно указать, что тип также соответствует B:

extension A where Self: B { 
    var b : UIView { 
     return self.a 
    } 
} 

Затем сделайте ваш тип соответствует A и B, например

struct MyStruct : A, B { 
    var a : UIView { 
     return UIView() 
    } 
} 

В связи с расширением протокола, экземпляры MyStruct будет иметь возможность использовать a и b, даже если только a был реализован в MyStruct:

let obj = MyStruct() 
obj.a 
obj.b 
+2

Я использовал «где Self: B ...» в прошлом, но он по-прежнему требует определения вашего «MyStruct» ». «MyStruct» - это «одноразовый» мост, который влечет за собой код плиты котла. Я ищу наиболее сжатый способ, так что мне не нужно создавать промежуточную конструкцию для выполнения сопоставления. В идеале я мог бы расширить протокол, так как мы можем расширить класс или структуру. –

+0

Я немного смущен, в этом случае вы не могли бы объединить использование 'where Self: B' и расширения протокола? – ABakerSmith

+0

@ABakerSmith вы пытались скомпилировать код выше? Я также пробовал этот подход, но компилятор все еще говорил, что MyStruct не соответствует протоколу B. Мой протокол B от третьей стороны и написан в Objective C. – Mingming

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