//: Playground - noun: a place where people can play
import UIKit
var str = "Hello, playground"
//协议的语法
//协议的定义方式与类,结构体,枚举的定义非常相似。
protocol FirstProtocol {
// 协议内容
}
protocol AnotherProtocol {
}
class SomeSuperClass {
}
//要使类遵循某个协议,需要在类型名称后加上协议名称,中间以冒号:分隔,作为类型定义的一部分。遵循多个协议时,各协议之间用逗号,分隔。
struct SomeStructure: FirstProtocol, AnotherProtocol {
// 结构体内容
}
//如果类在遵循协议的同时拥有父类,应该将父类名放在协议名之前,以逗号分隔。
class SomeClass:SomeSuperClass, FirstProtocol, AnotherProtocol {
//类的内容
}
//对属性的规定
/*
指定是存储型属性(stored property)还是计算型属性(calculate property)。此外还必须指明是只读的还是可读可写的。
如果协议规定属性是可读可写的,那么这个属性不能是常量或只读的计算属性。如果协议只要求属性是只读的(gettable),那个属性不仅可以是只读的,如果你代码需要的话,也可以是可写的。
协议中的通常用var来声明属性,在类型声明后加上{ set get }来表示属性是可读可写的,只读属性则用{ get }来表示。
*/
protocol SomeProtocol {
var mustBeSettable: Int {get set} ;
var doesNotNeedToBeSettable: Int { get };
}
//在协议中定义类属性(type property)时,总是使用static关键字作为前缀。当协议的遵循者是类时,可以使用class或static关键字来声明类属性,但是在协议的定义中,仍然要使用static关键字。
protocol AnotherPro {
static var someTypeProperty: Int {get set} ;
}
//这是一个含有一个实例属性要求的协议。
/*
FullyNamed协议除了要求协议的遵循者提供fullName属性外,对协议对遵循者的类型并没有特别的要求。这个协议表示,任何遵循FullyNamed协议的类型,都具有一个可读的String类型实例属性fullName。
*/
protocol FullyNamed {
var fullNaem:String {get} ;
}
//遵循FullyNamed协议的简单结构体
struct Person: FullyNamed {
var fullNaem: String ;
}
let john = Person(fullNaem: "John Applessed") ;
/*
这个例子中定义了一个叫做Person的结构体,用来表示具有名字的人。从第一行代码中可以看出,它遵循了FullyNamed协议。
Person结构体的每一个实例都有一个叫做fullName,String类型的存储型属性。这正好满足了FullyNamed协议的要求,也就意味着,Person结构体完整的遵循了协议。(如果协议要求未被完全满足,在编译时会报错)
*/
//更为复杂的类,它采用并遵循了FullyNamed协议:
class Starship: FullyNamed {
var prefix: String?
var name: String
init(name: String, prefix: String? = nil) {
self.name = name
self.prefix = prefix
}
var fullName: String {
return (prefix != nil ? prefix! + " " : "") + name
}
}
var ncc1701 = Starship(name: "Enterprise", prefix: "USS")