Swift 2.0 or later
下面的代码定义了一个结构体Pizza和一个协议Pizzeria,这个协议有一个包含makeMargherita()函数的扩展。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | struct Pizza { let ingredients: [String] } protocol Pizzeria { func makePizza(ingredients: [String]) -> Pizza func makeMargherita() -> Pizza } extension Pizzeria { func makeMargherita() -> Pizza { return makePizza(["tomato", "mozzarella"]) } } |
现在你将要定义一个如下的Lombardi的餐馆:
1 2 3 4 5 6 7 8 | struct Lombardis: Pizzeria { func makePizza(ingredients: [String]) -> Pizza { return Pizza(ingredients: ingredients) } func makeMargherita() -> Pizza { return makePizza(["tomato", "basil", "mozzarella"]) } } |
下面的代码创建了Lombardis类型的两个实例对象,哪一个对象会产生一个带有basil的margherita披萨?
1 2 3 4 5 | let lombardis1: Pizzeria = Lombardis() let lombardis2: Lombardis = Lombardis() lombardis1.makeMargherita() lombardis2.makeMargherita() |
两个都可以。Pizzeria协议声明了makeMargherita()方法并且提供了一个默认的实现,而且它又在Lombardis的实现中被重写。在这两种情况下,由于这个方法在协议中被声明,那么在运行时相应的实现就会被调用。
假如Pizzeria协议没有声明makeMargherita()方法,但是扩展中仍然提供了如下的代码的这个方法默认的实现,会发生什么?
这种情况下,只有lombardis2会产生一个带有basil的pizza,而lombardis1将会产生一个不带basil的pizza,原因是它会调用扩展中定义的那个方法。