十七、拓展

/*
 swift的扩展有点儿类似于OC的分类
 扩展可以分为枚举、结构体、类、协议添加功能,可以添加方法、计算属性、下标、(便捷)初始化器、嵌套类型、协议等等.
 扩展不能办到的事情:不能覆盖原有的功能、不能添加存储属性,不能向已有的属性添加属性观察器,不能添加父类、不能添加指定初始化器,不能添加反初始化器
 */
//1.计算属性、下标、方法、嵌套类型
var arr: Array<Int> = [10, 20, 30]
extension Array {
    subscript(nullable idx: Int) -> Element? {
        if (startIndex..<endIndex).contains(idx) {
            return self[idx]
        }
        return nil
    }
}
print(arr[nullable: 10] as Any) //越界返回nil

extension Int {
    func repeats(task: () -> Void) {
        for _ in 0..<self {
            task()
        }
    }
    mutating func square() -> Int { //方法
        self = self * self
        return self
    }
    enum Kind { //嵌套类型
        case negative, zero, positive
    }
    var kind: Kind {
        switch self {
        case 0:
            return .zero
        case let x where x > 0: return .positive
        default: return .negative
        }
    }
    subscript(digitIndex: Int) -> Int { //下标
        var decimalBase = 1
        for _ in 0..<digitIndex {
            decimalBase *= 10
        }
        return (self / decimalBase) % 10
    }
}

2.repeats {
    print(1) //1   //1
}
var age = 10
age.square()
print(age) //100

print(10.kind) //positive
age = 456
print(age[2]) //2 -> 4, 1 -> 5, 0 -> 6, >=3 -> 0, <0 崩溃没写好

//2.协议、初始化器
class Person {
    var age: Int
    var name: String
    init(age: Int, name: String) {
        self.age = age
        self.name = name
    }
}
extension Person : Equatable { //拓展协议
    static func == (left: Person, right: Person) -> Bool {
        left.age == right.age && left.name == right.name
    }
    convenience init() { //拓展便捷初始化器,不能拓展指定初始化器
        self.init(age: 0, name: "")
    }
}

struct Point {
    var x: Int = 0
    var y: Int = 0
}
extension Point { //拓展自定义初始化器可以保留自动生成的初始化器
    init(_ point: Point) {
        self.init(x: point.x, y: point.y)
    }
}
//编译器默认生成的4个初始化器
var p1 = Point()
var p2 = Point(x: 10)
var p3 = Point(y: 20)
var p4 = Point(x: 10, y: 20)
var p5 = Point(p4) //自定义初始化器

//协议和拓展
protocol Runnable {
    init(age: Int)
}
class Person0 {}
//extension Person0 : Runnable {
//    required init(age: Int) { //required初始化器也不能写在拓展中
//
//    }
//}

//如果一个类型已经实现了协议的所有要求,但是还没有声明它遵守了这个协议,可以通过拓展来让它遵守这个协议
protocol TestProtocol {
    func test()
}
class TestClass {
    func test() {
        print("test")
    }
}
extension TestClass : TestProtocol {}

//编写一个函数,判断一个整数是否为奇数
func isOdd<T : BinaryInteger> (_ i: T) -> Bool {
    i % 2 != 0
}
var num: Int8 = 10
print(isOdd(num)) //false

//等价
extension BinaryInteger {
    func isOdd() -> Bool {
        self % 2 != 0
    }
}
print(10.isOdd()) //false
print((-3).isOdd()) //true

//拓展可以给协议提供默认实现,也间接实现可选协议的效果
//拓展可以给协议补充协议中从未声明过的方法
protocol TestNumProtocol {
    func test1()
}
extension TestNumProtocol {
    func test1() {
        print("TestNumProtocol test1")
    }
    func test2() {
        print("TestNumProtocol test2")
    }
}
class TestNumClass : TestNumProtocol {}
var cls = TestNumClass()
cls.test1() //TestNumProtocol test1
cls.test2() //TestNumProtocol test2
var cls2 : TestNumProtocol = TestNumClass()
cls2.test1() //TestNumProtocol test1
cls2.test2() //TestNumProtocol test2

class TestNumClass1 : TestNumProtocol {
    func test1() {
        print("TestNumClass1 test1")
    }
    func test2() {
        print("TestNumClass1 test2")
    }
}
var cls3 = TestNumClass1()
cls3.test1() //TestNumClass1 test1
cls3.test2() //TestNumClass1 test2
var cls4 : TestNumProtocol = TestNumClass1()
cls4.test1() //TestNumClass1 test1 //去协议找
cls4.test2() //TestNumProtocol test2 //协议直接没有去拓展找

//3.泛型
class Stack<E> {
    var elements = [E]()
    func push(_ element: E) {
        elements.append(element)
    }
    func pop() -> E {
        elements.removeLast()
    }
    func size() -> Int {
        elements.count
    }
}
extension Stack {
    func top() -> E { //拓展中依然可以使用原类型中的泛型类型
        elements.last!
    }
}
extension Stack : Equatable where E : Equatable { //符合条件才拓展
    static func == (left: Stack, right: Stack) -> Bool {
        left.elements == right.elements
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值