swift里强大的协议
swift里的协议,可以当做类型使用。
可以作为函数的形参,以及返回值
作为常量、变量、以及属性类型
作为数组、字典等其他存储类型的元素的类型
协议的基本使用
protocol CustomProtocol {
//注意:协议里定义属性,必须制定样式,可读、可写。 定义协议属性使用var
// 默认遵循协议必须实现对应属性、方法
var customName: String { get }
var age: Int { get set}
//在协议中定义类型属性,要加static关键字
static var temp: String { get }
//定义方法 可以实例方法,也可以类方法. 方法参数不可以有默认值. 方法不用大括号
func addProtocolFunction(_ name: String)
func anotherProtocolFunction(age: Int) -> String
//协议也可以定义初始化器. 遵循协议的类必须使用required关键修饰
init(someParams: String)
//可选类型 添加@objc, 可以与OC混合变成。 只能被继承自OC类或者其他objc锁遵循,结构体枚举也不行
@objc
}
//某个类遵循协议。 如果你没有实现协议内容,会报错, 默认必须实现
class Person: CustomProtocol {
// 协议里的初始化器
required init(someParams: String) {
}
var age: Int = 0
var customName: String {
return "customName"
}
static var temp: String = "New temp"
func anotherProtocolFunction(age: Int) -> String {
return "another protocol func"
}
func addProtocolFunction(_ name: String) {
print("Protocol func")
}
}
协议继承
//子类继承并遵循o某个协议写法.
//如果子类重写了父类的指定初始化器,并x遵循协议实现了初始化器要求,那么要为这个初始化器加上required override 关键字
class Child: Person, CustomProtocol {
required override init() {
}
}
//x协议也可以继承
protocol subProtocol: CustomProtocol {
}
//类专用协议 添加anyObject关键字
protocol SomeOnlyClassProtocol: AnyObject {
//只能s类遵循的协议,结构体枚举不可以使用
}
协议组合
//协议组合 多个协议使用&链接
protocol Name {
var name: String { get }
}
protocol Age {
var age: Int { get }
}
class Man: Name, Age {
var name: String = ""
var age: Int = 0
init(name: String, age: Int) {
self.name = name
self.age = age
}
}
//协议组合 &
func happyBirthDay(man: Name & Age) {
print("name :\(man.name) age: \(man.age)")
}
let man = Man(name: "zhangsan", age: 30)
happyBirthDay(man: man) // name :zhangsan age: 30
//在扩展里添加协议
//有条件的遵循某个协议
extension Array: Name where Element: Name {
var name: String {
return "new Name"
}
}
//协议也可以扩展
extension Name {
func extensionFunc() -> Void {
print("协议扩展方法")
}
}
由于很多种语言都不支持多继承。 所以可以使用POP(面向协议编程)来解决类似多继承的问题。
面向对象编程(Object Oriented Programming,OOP,面向对象程序设计)
继承机制带来的问题: 由于不支持多继承,因此会在父类里塞入很多无关的属性及方法,这在以后的子类里可能会出现误使用。
修改结构很困难,不确定对父类或子类的影响。 pop修改行为,只修改具体的方法即可,这比修改结构简单多了。
OOP:主要关心对象是什么 POP:主要关心对象做什么
举个栗子🌰:
登录界面,校验用户名及密码。
OOP: 一般就直接在VC里添加两个函数,判断用户名、密码是否正确。 在优一点的,单独写一个工具类,来做校验。
使用的时候,初始化两个对象,来分别判断用户名及密码。
POP: 写一个协议,使用扩展,做用户名及密码的校验,后续再有什么新增校验方法,都在这里加就好了。
使用:直接让登录类遵循协议,就可以直接使用判断方法了。
//校验用户名及密码协议
protocol CheckUsenamePasswordProtocol {
func checkUseName(usename: String) -> Bool
func checkPassword(password: String) -> Bool
}
//扩展实现校验方法。 如果后续在加什么额外的条件,直接在这里加即可
extension CheckUsenamePasswordProtocol {
func checkUseName(usename: String) -> Bool {
if usename.count <= 0 {
return false
}else if usename == "username" {
return false
}else {
return true
}
}
func checkPassword(password: String) -> Bool {
if password.count < 6 {
return false
}else if password.contains("@#$%!") {
return false
}
return true
}
// //使用guard 方式 遵循黄金大道编程习惯
// func TestGoldRoadFunction(str: String) -> Bool {
// guard str.count < 6 else {
// return false
// }
// guard str.contains("#$%@") else {
// print("没有特殊字符")
// return false
// }
// guard str.count > 12 else {
// print("太长了")
// return false
// }
// return true
// }
}
//使用
class Login: CheckUsenamePasswordProtocol {
func loginButton() -> Void {
//直接就能调用校验方法
if checkUseName(usename: "name") && checkPassword(password: "password"){
print("成了")
}
}
}
let login = Login()
login.loginButton()