Swift学习_扩展和协议

Swift

1.扩展

扩展用于为已存在的类、结构体或枚举等类型添加新的功能

1.扩展计算型属性

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

let oneKilometer = 1.km
print("一公里等于\(oneKilometer)米")

let tenmilimeter = 10.mm
print("10毫米等于\(tenmilimeter)米")

let aMarathon = 43.km + 195.m
print("马拉松的长度是\(aMarathon)米")

2.扩展构造函数

扩展构造函数是为一个类型(类、结构体、枚举)添加新的构造函数

struct Size{
    
    var width = 0.0, height = 0.0
}

struct Point {
    
    var x = 0.0, y = 0.0
}

struct Rect {
    
    var origin = Point()
    var size = Size()
}

let defaultRect = Rect()
let memberwiseRect = Rect(origin:Point(x:2.0,y:2.0),size:Size(width:5.0,height:5.0))


extension Rect{
    
    init(center:Point,size:Size) {
        let originX = center.x - size.width/2
        let originY = center.y - size.height/2
        self.init(origin:Point(x: originX, y: originY),size:size)
    }
}

let centerRect = Rect(center: Point(x: 4.0, y: 4.0), size: Size(width: 3.0, height: 3.0))

print("默认构造函数实例\(defaultRect)")
print("成员构造函数实例\(memberwiseRect)")
print("扩展构造函数实例\(centerRect)")

3.扩展方法

extension Int{
    
    static var num:Int = 4
    func legInt() -> Int {
        
        return self * Int.num
    }
    
    // 定义一个可变方法
    mutating func legInt1(){
        
        self = self * Int.num
    }
}

let cat = 6.legInt()
print("6只猫有\(cat)条腿")

var cat1 = 6
cat1.legInt1()
print("6只猫有\(cat1)条腿")

使用 mutating 关键字修饰方法是为了能在该方法中修改 struct 或是 enum 的变量,在设计接口的时候,也要考虑到使用者程序的扩展性。所以要多考虑使用mutating来修饰方法。

4.扩展下标

extension Int{
    
    subscript(i:Int) -> Int{
        
        var base = 1
        
        for _ in 0..<i {
            
            base *= 10
        }
        return (self / base) % 10
    }
}

print("输出个位的值:\(7643[0])")
print("输出十位的值:\(7643[1])")
print("输出白位的值:\(7643[2])")
print("输出千位的值:\(7643[3])")
print("输出万位的值:\(7643[4])")

subscript(自定义下标):在swift中,subscript可以帮助我们更方便的访问或者设置一个集合中的某个成员。

2.协议

swift中的协议用于定义方法和属性,但协议本身并不进行实现,而是由采纳该协议的类具体实现,与Objective-C不用的是,协议还可以被结构体和枚举采纳。

定义协议

protocol 协议名称{
    
    // 协议内容
}
protocol 协议名称2{
}

protocol 协议名称1:class {
    
    // 协议内容
}

采纳协议

struct 结构体名称:协议名称 {
    
    // 结构体内容
}

采纳多个协议

struct 结构体名称1:协议名称,协议名称2
{
    //结构体名称
}

class 子类名称: 父类名称,协议名称 {
    
}

协议对方法的要求

protocol Animal{
    
    // 在协议中声明实例方法
    func shout()
    // 在协议中声明类方法
    static func eat()
}

class Dog: Animal {
    
    func shout() {
        
        print("汪汪汪")
    }
    
    static func eat() {
        
        print("吃骨头")
    }
}

在协议中声明可变方法

protocol Button{
    
    mutating func toggle()
}

enum OnOffSwitch:Button {
    
    case Off,On     // 定义两个枚举值
    
    mutating func toggle() {
        
        if self == OnOffSwitch.On{
            
            self = .Off
            print("off")
        }else{
            
            self = .On
            print("on")
        }
    }
}

var lightSwitch = OnOffSwitch.Off //关
lightSwitch.toggle() //开
lightSwitch.toggle() //关
lightSwitch.toggle() //开

协议对构造函数的要求

protocol MakeFood{
    
    init()
}

class Personx {
    
    init(){
        
        print("人会做饭")
    }
}

class Cook: Personx,MakeFood {
    
    required override init() {
        
        print("厨师做的饭更好吃")
    }
}

可选协议

可选协议表示定义协议的属性和方法可以实现也可以不实现

@objc protocol Animals{
    
    @objc optional func wing()
}

class Bird: Animals {
    
    @objc func wing() {
        
        print("鸟的翅膀")
    }
}

// 这个实现方法不写也不会报错,例如下面例子
class Tiger:Animals{
    
}

let bird = Bird()
bird.wing()

协议作为类型使用

  1. 作为函数、方法或构造函数中的参数类型或返回值类型
  1. 作为常量、变量或属性的类型
  1. 作为数组、字典或其他容器中的元素类型
protocol Name{
    
    var name:String{get}
}

struct Student:Name {
    
    var name:String
}

func contact(student:Name){
    print("要联系的学生的名字是\(student.name)")
}

let student = Student(name:"小米")
contact(student: student)
print(student.name)

扩展和协议结果输出

代码已上传至git:
--> 传送门:Swift_基本语法

附录

查看完整专栏《Swift学习》

有问题欢迎指正以及相互探讨 —— CoderSun

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,525评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,203评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,862评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,728评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,743评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,590评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,330评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,244评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,693评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,885评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,001评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,723评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,343评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,919评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,042评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,191评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,955评论 2 355

推荐阅读更多精彩内容

  • importUIKit classViewController:UITabBarController{ enumD...
    明哥_Young阅读 3,812评论 1 10
  • 1、范型范型所解决的问题 函数、方法、类型:类,结构体,枚举,元组类型,协议参数,返回值,成员函数参数,成员属性类...
    我是小胡胡123阅读 829评论 0 1
  • 136.泛型 泛型代码让你可以写出灵活,可重用的函数和类型,它们可以使用任何类型,受你定义的需求的约束。你可以写出...
    无沣阅读 1,472评论 0 4
  • 132.转换错误成可选值 通过转换错误成一个可选值,你可以使用 try? 来处理错误。当执行try?表达式时,如果...
    无沣阅读 1,257评论 0 3
  • Swift属性 Swift属性将值跟特定的类,结构体,枚举关联。分为存储属性和计算属性,通常用于特定类型的实例。属...
    小小厨师阅读 854评论 0 0