Skip to content

Instantly share code, notes, and snippets.

@LeeKahSeng
Created August 18, 2017 08:52
Show Gist options
  • Save LeeKahSeng/dec7d7b664f24acbb248da496b6a3a84 to your computer and use it in GitHub Desktop.
Save LeeKahSeng/dec7d7b664f24acbb248da496b6a3a84 to your computer and use it in GitHub Desktop.
protocol Animal {
var name: String { get }
func walk()
associatedtype FoodType
func eat(food: FoodType)
}
class Cow: Animal {
let name: String
init(withName name: String) {
self.name = name
}
func walk() {
print("\(name) is walking in the farm.")
}
// Cow should eat grass
func eat(food: Grass) {
print("\(name) eat \(food.foodName)")
}
}
class Tiger: Animal {
let name: String
init(withName name: String) {
self.name = name
}
func walk() {
print("\(name) is walking in the jungle.")
}
// Tiger should eat meat
func eat(food: Meat) {
print("\(name) eat \(food.foodName)")
}
}
// Food for cow
struct Grass {
let foodName = "Grass"
}
// Food for tiger
struct Meat {
let foodName = "Meat"
}
enum AnyAnimal: Animal {
case cow(Cow)
case tiger(Tiger)
var name: String {
switch self {
case let .cow(animal):
return animal.name
case let .tiger(animal):
return animal.name
}
}
func walk() {
switch self {
case let .cow(animal):
animal.walk()
case let .tiger(animal):
animal.walk()
}
}
func eat(food: Any) {
switch self {
case let .cow(animal):
// Make sure we only feed grass to cow
if let f = food as? Grass {
animal.eat(food: f)
}
case let .tiger(animal):
// Make sure we only feed meat to tiger
if let f = food as? Meat {
animal.eat(food: f)
}
}
}
}
// Create concrete type Animal
let myTiger = Tiger(withName: "My Tiger")
let myCow = Cow(withName: "My Cow")
// Instantiate AnyAnimal with concrete type Animal
let anyTiger = AnyAnimal.tiger(myTiger)
let anyCow = AnyAnimal.cow(myCow)
let animalArray: [AnyAnimal] = [anyTiger, anyCow]
let foodArray: [Any] = [Meat(), Grass()]
for (anyAnimal, food) in zip(animalArray, foodArray) {
anyAnimal.walk()
anyAnimal.eat(food: food)
// Output:
// My Tiger is walking in the jungle.
// My Tiger eat Meat
// My Cow is walking in the farm.
// My Cow eat Grass
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment