swift之基本协议与自定义协议

14 篇文章 0 订阅

一、协议

1.1-什么是协议及基本用法

/*
协议可以用来定义方法、属性、下标的申明,协议可以被枚举、结构体、类遵守
遵循多个协议用逗号隔开
	struct SomeStructure: SomeProtocol, AnotherProtocol {
	    //这里是结构体的定义部分
	}
协议中定义方法时不能有默认参数
默认情况下协议中定义的内容必须全部都实现
拥有父类的类在遵循协议时,需要将父类名放在协议名之前
	class SomeClass: SomeSuperClass, SomeProtocol, AnotherProtocol {
	    //这里是类的定义部分
	}

属性要求:
1.协议可以定义实例属性和类型属性(使用static);
2.协议不指定属性是存储属性还是计算型属性,只指定属性名称和类型以及读写性;
3.协议指定属性的读取类型,使用的get和set,中间不能使用逗号;
4.协议总是使用var关键字来声明变量属性;
5.不能给协议属性设置默认值,因为默认值被看做是一种实现;

方法要求:
1.协议可以定义实例方法和类方法(使用static);
2.协议定义函数时不能添加函数的实现,同时,传入的参数也不能使用默认参数;
3.如果协议定义的实例方法会改变实例本身,需要在定义的方法名前使用mutating;这使得结构体和枚举能够遵循此协议并满足此方法要求。

语法:
protocol SomeProtocol {
    //这里是协议的定义部分
}
protocol AnotherProtocol{
    //这里是协议的定义部分
}
*/

protocol PersonFrame {
    func speak()
    var age: Int{get set}
    var name: String{get}
    subscript(index:Int)->Int{get set}
}
class Person: PersonFrame{
    var age:Int=1
    var name:String="simonwang" // or let.
    func speak(){
        print("person speak.")
    }
    subscript(index: Int) -> Int {
        set {}
        get {index}
    }
    
}
var p = Person()
//或者用计算属性实现
class Person: PersonFrame{
    var age:Int{
        get {0}
        set {}
    }
    var name:String {"simonwang"}
    func speak() {
        print("person speak.")
    }
    subscript(index: Int) -> Int {
        get { 0 }
        set { index }
    }
}

1.2-static、class

/*
为了保证通用,协议必须用static定义类型方法、类型属性、类型下表,因为class只有类可以使用
*/

protocol PersonFrame {
    static func speak()
}
class Person1: PersonFrame{
    class func speak() {
        print("person1 speak.")
    }
}
class Person2: PersonFrame{
    static func speak() {
        print("person2 speak.")
    }
}
struct Person3 {
    static func speak(){
        print("person3 speak.")
    }
}
Person1.speak()
输出:person1 speak.
Person2.speak()
输出:person2 speak.
Person3.speak()
输出:person3 speak.

1.3-mutating

/*
只有将协议中的实例方法标记为mutating才允许结构体、枚举的具体实现修改自身内存
类在实现方法时不用加mutating,枚举、结构体才需要加mutating
*/

protocol PersonFrame {
    mutating func speak()
}
class Person1: PersonFrame{
    var age:Int = 1
    func speak() {
        age=2
        print("i am \(age)")
    }
}
struct Person2:PersonFrame {
    var age:Int=1
    mutating func speak() {
        age=3
        print("i am \(age)")
    }
}

var p1=Person1()
p1.speak()
i am 2
var p2=Person2()
p2.speak()
i am 3

1.4-init

/*
协议中还可以定义初始化器init
非final类实现时必须加上required
如果从协议实现的初始化器,刚好是重写了父类的指定初始化器,那么这个初始化必须同时加required、override,之前说的不用加override是因为没有协议
*/

protocol PersonFrame {
    init(age:Int,name:String)
}
class Person1: PersonFrame{
    required init(age: Int, name: String) {
        // 初始化内容
    }
}
final class Person2:PersonFrame {
    init(age: Int, name: String) {
        // 初始化内容
    }
}


protocol PersonFrame {
    init( age:Int )
}
class Person{ //未继承协议
    init(age: Int){}
}
class Child : Person, PersonFrame{
    required override init(age:Int){ //同时加required override
        super.init(age: age)
    }
}

1.5-init\init?\init!

/*
协议中定义的init?\init!,可以用init\init?\init!去实现
协议中定义的init,可以用init\init!去实现
*/

protocol PersonFrame {
    init()
    init?(age:Int)
    init!(num:Int)
}
class Person:PersonFrame{
    required init(){}
//    required init!(){}
    
    required init?(age:Int){}
//    required init!(age:Int){}
//    required init(age:Int){}
    
    required init!(num:Int){}
//    required init?(num:Int){}
//    required init(num:Int){}
}


1.6-协议的继承

/*
PersonFrame协议继承Liveable协议
*/

protocol Liveable {
    func breath()
}
protocol PersonFrame:Liveable {
    var age:Int{get set}
}
class Person:PersonFrame{
    var age:Int = 1
    func breath() {
        print("person breath.")
    }
}
var p1=Person()

1.7-协议组合

/*
协议组合,可以包含1个类类型(最多一个)
*/
protocol Liveable {}
protocol PersonFrame {}
class Person{}

func fu0(obj:Person){}
func fn1(obj:Liveable){}
func fn2(obj:Liveable & PersonFrame){}
func fn3(obj:Person&Liveable&PersonFrame){}

typealias  RealPerson = Person & Liveable & PersonFrame

func fn4(obj:RealPerson){}

1.8-CaseIterable协议

/*
枚举遵守CaseIterable协议可以实现遍历枚举值
*/
enum Test:CaseIterable {
    case up,down,left,right
}
let test = Test.allCases
print(test.count)
输出:4
for t in test{
    print(t)
}
输出:
up
down
left
right

1.9-CustomStringConvertible协议

/*
遵守CustomStringConvertible、 CustomDebugStringConvertible协议,都可以自定义实例的打印字符串
print调用的是CustomStringConvertible协议的description
debugPrint、po调用的是CustomDebugStringConvertible协议的debugDescription
*/
 class Person : CustomStringConvertible, CustomDebugStringConvertible {
    var age = 0
    var description: String { "person_\(age)"}
    var debugDescription: String { "debug_person_\(age)" }
 }
var person = Person()
 print(person)
 debugPrint(person)
输出:
person_0
debug_person_0

1.10-Any、AnyObject

/*
Swift提供了2种特殊的类型:Any、AnyObject 
Any:可以代表任意类型(枚举、结构体、类,也包括函数类型)
AnyObject:可以代表任意类类型(在协议后面写上: AnyObject代表只有类能遵守这个协议)
在协议后面写上: class也代表只有类能遵守这个协议
*/
class Test{}
var stu: Any = 10
stu = "test"
stu = Test()

// 创建1个能存放任意类型的数组
var data = [Any]()
data.append(1)
data.append(3.14)
data.append(Test())
data.append("test")
data.append({ 10 })

1.11-is、as?、as!、as

/*
is用来判断是否为某种类型,as用来强制类型转换
*/
protocol Liveable {}
class Person{}
class Child:Person,Liveable{
    func speak(){
        print("Child speak")
    }
    func walk(){
        print("Child walk")
    }
}
var cld : Any=1
print(cld is Int) //true
cld="a"
print(cld is String) //true
cld=Child()
print(cld is Child) //true
print(cld is Person) //true
print(cld is Liveable) //true

var cld : Any=1
(cld as? Child)?.speak() //没调用speak()
cld = Child()
(cld as? Child)?.speak() //Child speak
(cld as! Child).speak() //Child speak
(cld as? Child)?.walk() //Child walk

var data = [Any]()
data.append(Int("123") as Any)
data.append((String("test") as Any))
print(data)
输出:[Optional(123), "test"]
var d = 10 as Double
print(d)
输出:10.0

1.12-X.self、X.Type、AnyClass

/*
X.self是一个原类型metadata的指针,metadata存放着类型相关信息,X.self属于X.type类型
*/
class Person{}
class Child:Person{}
//var perType:Person.Type=Person.self
//var cldType:Child.Type=Child.self
//perType = Child.self

//var anyType:AnyObject.Type=Person.self
//anyType=Child.self
//
//public typealias AnyClass = AnyObject.Type
//var anyType2:AnyClass=Person.self
//anyType2=Child.self
var per = Person()
var perType = type(of: per)
print(Person.self==type(of: per)) //true

1.13-元类型的应用

class Animal {required init(){}}

class Cat:Animal{}
class Dog:Animal{}
class Pig:Animal{}

func create(_ clses: [Animal.Type])->[Animal]{
    var arr=[Animal]()
    for cls in clses {
        arr.append(cls.init())
    }
    return arr
}
print(create([Cat.self,Dog.self,Pig.self]))

[test.Cat, test.Dog, test.Pig]

import Foundation
class Person {
    var age: Int = 0
}
class Student : Person {
    var no: Int = 0
}

print(class_getInstanceSize(Student.self))  //32
print(class_getSuperclass(Student.self)!)  //Person
print(class_getSuperclass(Person.self)!)  //_TtCs12_SwiftObject

swift源码

1.14-Self

//self代表当前类型
  class Person {
    var age = 1
    static var count = 2
    func run() {
        print(self.age)
        print(Self.count)
    }
}

protocol Liveable {
    func test() -> Self
}
class Person : Liveable {
    required init() {}
    func test() -> Self { type(of: self).init()}
}
class Child : Person {}
var p = Person()
print(p.test()) //test.Person
var cld  = Child()
print(cld.test()) //test.Child
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值