Reputation: 1414
I'm trying to create a protocol and a couple of classes that conform to it. The protocol has an property which conforms to another protocol so the classes each need to have a property that matches.
This is (something like) what I'm trying so far:
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?
}
The (relevant) error I'm getting is "Type 'ToffeeApple' does not conform to protocol 'Delicious'" (and the same for Banana and BananaSplit too). I thought the properties Apple
and Banana
would satisfy the requirements as they both conform to Edible
as as fruit
does. Am I declaring one of these incorrectly or is this not possible?
Many thanks.
Upvotes: 3
Views: 94
Reputation: 1882
Simply change from:
protocol Delicious {
func consume()
var fruit: Edible? { get set }
}
to:
protocol Delicious {
func consume()
associatedtype EdibleType: Edible
var fruit: EdibleType? { get set }
}
associatedtype EdibleType: Edible
means:
protocol Delicious
has an unprovided type EdibleType
which confirm to protocol Edible
.
And the type should be provided when something is confirm to Delicious
.
So in:
class ToffeeApple: Delicious {
func consume() {
print("I like toffee apples!")
fruit.eat()
// ...
}
typealias EdibleType = Apple
var fruit: Apple?
}
The EdibleType
is filled with Type Apple
,
And in:
class BananaSplit: Delicious {
func consume() {
print("Ah! A banana split!")
fruit.eat()
// ....
}
typealias EdibleType = Banana
var fruit: Banana?
}
The EdibleType
is filled with Type Banana
,
If you want learn more about this you can search around Swift Generics.
Upvotes: 2
Reputation: 2291
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!
Upvotes: 2