swift. 扩展类添加属性_跟我学Swift 5.2扩展

介绍

  • 可以给现有的类、结构体、枚举类型、协议添加新的功能。

  • 扩展可以:

    • 添加计算属性

    • 定义方法

    • 提供新的构造函数

    • 使现有的类型遵守某协议

  • 使用extension关键字实现扩展。

语法

  • 直接扩展某个类型

extension SomeType {
// new functionality to add to SomeType goes here
}
  • 扩展某个类型以遵守一个或多个协议,但不能是继承某个类

extension SomeType: SomeProtocol, AnotherProtocol {
// implementation of protocol requirements goes here
}

扩展计算属性

  • 扩展可以向已有的类型添加计算实例属性和计算类型属性。

extension Double {
var km: Double { return self * 1_000.0 }
var m: Double { return self }
var cm: Double { return self / 100.0 }
var mm: Double { return self / 1_000.0 }
}
25.0.km
25.0.m
25.0.cm
25.0.mm

扩展构造函数

  • 对于结构体,可直接添加新的构造函数。

struct Animal {
var species: String

init(species: String) {

self.species = species
}
}

extension Animal {

init(name: String) {
self.init(species:name)
}
}
  • 对于类,只能添加新的便利构造函数。

class Animal {
var species: String

init(species: String) {
self.species = species
}
}

extension Animal {

convenience init(name: String) {
self.init(species:name)
}
}

扩展方法

  • 扩展可以为已有的类型添加新的实例方法和类型方法。

class Student {
}

extension Student {
// 实例方法
func play(){
print("play")
}

// 类型方法
class func study(){
print("study")
}
}


let stu = Student()
stu.play()

Student.study()

扩展mutating方法

  • 扩展结构体,如果要修改属性的值,必须在方法面前加上mutating

struct Student {  
var age: Int = 10
}

extension Student {
// 实例方法
mutating func play(){
age = 20
print("play")
}
}

// 此时要用var
var stu = Student()
stu.play()

面向协议编程POP

为什么面向协议?

假如有类继承关系如下:B、C 继承自 A,B1、B2 继承自 B,C1、C2 继承自 C。如果 B1 和 C2 具有某些共同特性,可以有两种做法:

  1. 找到 B1 和 C2 的最近祖先 A,然后在 A 中添加共同特性代码,这样做的结果是 A 的代码会越来越庞大臃肿,维护起来非常困难。

  2. 声明一个具有共同特性的协议,让 B1 和 C2 实现该协议,这样其实等于相同的代码写了两次,造成代码的重复。

  3. 使用协议扩展,它能够为协议中规定的方法提供默认实现。因此声明一个具有共同特性的协议,扩展该协议给出共同特性的实现,然后让 B1 和 C2 实现该协议,既不影响类的继承结构,也不需要写重复代码。

Swift如何实现?

针对某个需要实现的功能,可以使用协议定义出接口,然后利用协议扩展提供默认的实现。需要这个功能,只需要声明遵守了这个协议即可,遵守某个协议的对象调用协议声明的方法时,如果遵守者本身没有提供实现,协议扩展提供的默认实现会被调用。

  • 案例:如果有100个协议的遵守者实现都一样,会有大量重复代码。

protocol Eatable {
func eat()
}

// 遵守协议
class Person: Eatable {
func eat() {
print("吃饭了")
}
}

var p = Person()
p.eat()
  • 改进:在协议的扩展中给出方法的默认实现,则协议遵守者中可省略。

extension Eatable {
func eat() {
print("吃饭了")
}
}

class Person: Eatable {
}

var p = Person()
p.eat()
  • 如果某个遵守者需要独特的实现,自己再实现协议中的方法即可。

class Person: Eatable {    
func eat() {
print("人要吃饭了")
}
}

var p = Person()
p.eat()

备注:后续文章首发于微信公众号,除了 Swift、SwiftUI、Combine、iOS 开发等实用技术,也会分享一些学习心得,欢迎大家关注。

我的公众号

a763c30cef51c4a2a73dc9fabca61a77.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值