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

How do a conform to a protocol that declares property of type protocol?

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

这是(类似的)我目前正在尝试的:

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' does not conform to protocol 'Delicious'"(对于 Banana 和 BananaSplit 也是如此)。我认为属性 AppleBanana 会满足要求,因为它们都符合 Ediblefruit 一样。我是否错误地声明了其中之一,或者这是不可能的?

非常感谢。

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!

只需更改:

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。