//协议
protocol Named {
var name:String{ get set } //定义实例属性
static var className:String{ get }
init(name:String) //定义构造方法
func showName() //定义实例方法
static func showClassName() //定义类方法
}
protocol Scored {
var score:Double{ get set }
}
//Users遵循Named协议
class Users: Named {
var name: String
var age:Int = 0
static var className: String{
return "\(self)"
}
//协议中规定的构造方法,必须使用required关键字声明
required init(name:String) {
self.name = name
}
//遵循showName方法
func showName() {
print("Name=\(name)")
}
//遵循showClassName方法
static func showClassName() {
print("ClassName is \(self)")
}
}
//Pupil继承Users并且遵循Scored
//遵循多个协议用,隔开
class Pupil: Users,Scored {
var score: Double = 0.0
//自定义构造方法
init(name:String,score:Double) {
self.score = score
super.init(name: name)
}
//实现协议中的构造方法
required init(name:String) {
super.init(name: name)
}
func test() {
print("\(self.name) is testing.")
}
}
//使用示例
let user = Users.init(name: "Jonny")
user.showName() //结果:Name=Jonny
print("ClassName = \(Users.className)") //结果:ClassName = Users
Users.showClassName() //结果:ClassName is Users
user.age = 25
//pupil声明为Named类型,调用test()方法时会报错
let pupil:Named = Pupil.init(name: "Jenny", score: 59)
pupil.showName() //结果:Name=Jenny
//函数中要求参数p必须实现两个协议
func showMessage(p:Named&Scored){
print("Name is \(p.name), score is \(p.score).")
}
let pupil1 = Pupil.init(name: "Jenny", score: 59)
showMessage(p: pupil1) //结果:Name is Jenny, score is 59.0.
let b1 = pupil is Scored //检测pupil是否遵循Scored协议
if b1 {
print("Yes")
}
//类型转化
if let pupil2 = pupil as? Scored {//如果pupil转化成了Scored类型,则返回实例,否则为nil
print("pupil2' score is \(pupil2.score)") //结果:pupil2' score is 59.0
}
let pupil3 = pupil as! Scored //强制转化,转化失败则会报错
print("pupil3' score is \(pupil3.score)") //结果:pupil3' score is 59.0
//扩展
//已上篇的Person类为例
extension Person{
//只能扩展便利构造方法
convenience init(age:Int) {
self.init(firstName:"",lastName:"",age:age)
}
//只能扩展计算属性,不能扩展存储属性
var personInfo:String{
return "firstName=\(firstName),lastName=\(lastName),age=\(age)."
}
//扩展实例方法
func sayHello() {
print("Hello world!")
}
//嵌套类型
enum SkinColor {
case yellow,white,black
}
//声明返回值可以不被引用
@discardableResult
//扩展类型方法
static func Skin()->[SkinColor]{
return [.yellow,.white,.black]
}
}
//使用实例
let p = Person.init(age: 18)
p.firstName = "Jenny"
p.lastName = "Yang"
print(p.personInfo) //结果:firstName=Jenny,lastName=Yang,age=18.
p.sayHello() //结果:
Hello world!for skin in Person.Skin() {//数组遍历
print("\(skin)") //结果:yellow、white、black
}