//拓展1-3
/*
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
}
}
网友评论