如何符合声明协议类型属性的协议?

时间:2016-09-27 09:05:55

标签: swift swift-protocols

我正在尝试创建一个协议和几个符合它的类。该协议具有符合另一个协议的属性,因此每个类都需要具有匹配的属性。

这是(类似的)到目前为止我正在尝试的事情:

protocol Edible {
    func eat()
}

class Apple:Edible {
    func eat() {
        print("Crunch")
    }
}

class Banana:Edible {
    func eat() {
        print("Homph")
    }
}

protocol Delicious {
    func consume()

    var fruit: Edible? { get set }
}    

class ToffeeApple: Delicious {
    func consume() {
        print("I like toffee apples!")
        fruit.eat()
        // ...
    }

    var fruit: Apple?
}

class BananaSplit: Delicious {
    func consume() {
        print("Ah! A banana split!")
        fruit.eat()
        // ....
    }

    var fruit: Banana?
}

我得到的(相关)错误是“Type'ToffeeApple'不符合协议'Delicious'”(香蕉和BananaSplit也是如此)。我认为属性AppleBanana会满足要求,因为它们都符合Ediblefruit。我是否错误地宣布其中一个或者这是不可能的?

非常感谢。

2 个答案:

答案 0 :(得分:2)

import UIKit

protocol Edible {
    func eat()
}

class Apple: Edible {
    func eat() {
        print("Crunch")
    }
}

class Banana:Edible {
    func eat() {
        print("Homph")
    }
}

protocol Delicious {
    func consume()

    var fruit: Edible? { get set }
}

class ToffeeApple: Delicious {
    var fruit: Edible?

    func consume() {
        print("I like toffee apples!")
        fruit?.eat()
    }

}

class BananaSplit: Delicious {
    var fruit: Edible?

    func consume() {
        print("Ah! A banana split!")
        fruit?.eat()
    }
}

let bananaSplit = BananaSplit()
bananaSplit.consume() // Ah! A banana split!

答案 1 :(得分:2)

只需更改:

protocol Delicious {
    func consume()

    var fruit: Edible? { get set }
}

为:

protocol Delicious {
    func consume()

    associatedtype EdibleType: Edible
    var fruit: EdibleType? { get set }
}

associatedtype EdibleType: Edible表示:

协议Delicious具有未提供的类型EdibleType,可以向协议Edible确认。

当确认Delicious时,应提供类型。

所以:

class ToffeeApple: Delicious {
    func consume() {
        print("I like toffee apples!")
        fruit.eat()
        // ...
    }

    typealias EdibleType = Apple
    var fruit: Apple?
}

EdibleType填充了Apple类型,

并在:

class BananaSplit: Delicious {
    func consume() {
        print("Ah! A banana split!")
        fruit.eat()
        // ....
    }

    typealias EdibleType = Banana
    var fruit: Banana?
}

EdibleType填充了Banana类型,

如果您想了解更多相关信息,可以搜索Swift Generics。