swift学习笔记之拓展和协议

前端之家收集整理的这篇文章主要介绍了swift学习笔记之拓展和协议前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
@H_502_1@/** * Protocol(协议)用于统一方法属性名称,而不实现任何功能。协议能够被类,枚举,结构体实现,满足协议要求的类,枚举,结构体被称为协议的遵循者。 遵循者需要提供协议指定的成员,如属性方法,操作符,下标等。 */ //使用protocol来声明一个协议。 /** * 协议的语法 协议的定义与类,结构体,枚举的定义非常相似,如下所示: protocol SomeProtocol { // 协议内容 } 在类,结构体,枚举的名称加上协议名称,中间以冒号:分隔即可实现协议;实现多个协议时,各协议之间用逗号,分隔,如下所示: struct SomeStructure: FirstProtocol,AnotherProtocol { // 结构体内容 } 当某个类含有父类的同时并实现了协议,应当把父类放在所有的协议之前,如下所示: class SomeClass: SomeSuperClass,FirstProtocol,AnotherProtocol { // 类的内容 } */ protocol ExampleProtocol { var simpleDescription: String { get } mutating func adjust() } //类,枚举和结构体都可以使用协议。 class SimpleClass: ExampleProtocol { var simpleDescription: String = "A very simple class." var anotherProperty: Int = 69105 func adjust() { simpleDescription += " Now 100% adjusted." } } var a = SimpleClass() a.adjust() let aDescription = a.simpleDescription struct SimpleStructure: ExampleProtocol { var simpleDescription: String = "A simple structure" mutating func adjust() { simpleDescription += " (adjusted)" } } var b = SimpleStructure() b.adjust() let bDescription = b.simpleDescription //注意在simpleStructure的声明中关键字mutating的使用,它用来标记这个方法修改了这个结构体。而在simpleClass的声明中则不需要使用mutating,因为类中的方法总是可以被修改的。 //二、协议(protocol) //可定义方法属性,由具体的类去实现. 越来越像Java //Swift中的协议能被类,枚举,结构体实现. protocol SomeProtocol{ //协议内容 } class SomeClass : SomeProtocol{ //实现协议,可实现多个协议 } //2.1 协议中属性/方法/突变方法的要求 //2.1.1 属性的要求 protocol AnotherProtocol1{ //class表示类成员(结构体/枚举中用static) static var property : Int { get set} //get,set 表示可读可写 } class AnotherClass1 : AnotherProtocol1{ class var property : Int { //实现协议中的属性 get{ return 10 } set{ } } } //2.1.2 方法要求 //不支持默认参数. 写法上只是没有方法的实现. protocol AnotherProtocol2{ func myFunc() -> Int //只声明不实现 } class AnotherClass2 : AnotherProtocol2{ func myFunc() -> Int { //实现方法 return 10 } } //2.1.3 突变方法要求 //能在方法函数内部改变实例类型的方法称为突变方法. (mutating关键字) //在类中,可以不写mutating,但在结构体与枚举中国必须写 protocol Togg{ mutating func togg() } enum OnOffSwitch : Togg{ case Off,On mutating func togg() { //改变实例的值 switch self{ case .Off: self = On case .On: self = Off } } } var lightSwitch = OnOffSwitch.Off lightSwitch.togg() //值变为On //2.2 协议类型. // 协议也可以当做类型来使用. 这点和函数一样. // 1.可作为参数/返回值类型 //2.可作为常量/变量/属性的类型 //3.可作为数组/字典和其他元素类型 protocol MyRect{ func myLuckNumber() -> Int } class MyRectImp : MyRect{ func myLuckNumber() -> Int { return 10 } } class Dice { let sides :Int var gener : MyRect //作为类型 init(sides:Int,gener:MyRect){ //作为参数 self.sides = sides self.gener = gener } } var dice = Dice(sides: 6,gener: MyRectImp()) dice.gener.myLuckNumber() //------------------------extention-------------- //使用extension来为已经存在的类型添加功能,就像新的方法和计算属性一样。你可以用extension为已经声明的类型添加协议,甚至是类库中自带的类型。 extension Int: ExampleProtocol { var simpleDescription: String { return "The number \(self)" } mutating func adjust() { self += 42 } } //使用协议名就像使用其他类型名一样——例如,创建一个不同类型对象的集合,但是这些对象都遵循一个单一的协议。当值的类型是协议类型时,在协议定义以外的方法是不可用的。 //[plain] view plaincopy在CODE上查看代码片派生到我的代码 let protocolValue: ExampleProtocol = a protocolValue.simpleDescription //即使protocolValue有一个运行时类型(simpleClass),编译器同样会把它看作是ExampleProtocol类型。也就是说,你不能访问除了遵循协议以外的类的方法属性 //一、扩展(extension) //扩展 extension (类似OC中的分类,但Swift中没有名字),即在没有权限获取到原始代码的情况下,为类增加功能. //注意: 只要定义了扩展,那么该扩展对该类的实例都是可用的. //extension SomeType{ // //添加到SomeType的新功能写在这里 //} //1.1扩展属性(只能是计算属性) //扩展可以添加新计算属性,但是不能添加存储属性(也不可以添加属性观察). extension Double{ //为API中的已有类型添加实例属性 var km : Double { return self * 1_000.0 } var m : Double { return self } var cm : Double { return self / 100.0 } } let jjLength = 1.m // 1与m进行点运算,表示1的Double值 let jjLength_km = 1.km print(10.km + 1.m) //1.2扩展构造器 //可以定制自己的构造器 class MyClass{ var a : Int init(){ a = 10 } } extension MyClass{ convenience init( parm:Int){ //扩展构造器 self.init() print("扩展构造器--->便利构造器,\(parm)") } } var myClass = MyClass(parm: 9) //1.3扩展方法 //下面是像Int中扩展myIntFunc方法 extension Int{ func myIntFunc(){ print("值为\(self),哈哈哈哈!") } } 1.myIntFunc() //1.3.1 修改实例方法 //通过扩展方法,可以修改该实例self本身.但是方法前要加 mutating extension Double{ mutating func myMoidfySelfValue() { self = self * self //修改self实例的值 } } var d = 2.0 d.myMoidfySelfValue() //1.4 扩展嵌套类型 //即向已有的嵌套类型中添加新的嵌套类型. 还可以扩展下标(附属脚本)等. extension Character { enum Kind{ //嵌套了一个枚举类型 case Big case Small } var k : Kind{ if(String(self).lowercaseString == "a"){ return Kind.Big }else{ return Kind.Small } } } var ch : Character = "a" ch.k //返回一个枚举值Kind.Big //1.5下标(Subscripts) //扩展可以向一个已有类型添加新下标。这个例子向Swift内建类型Int添加了一个整型下标。该下标[n]返回十进制数字从右向左数的第n个数字 //123456789[0]返回9 //123456789[1]返回8 //...等等 extension Int { subscript(digitIndex: Int) -> Int { var decimalBase = 1 for _ in 1...digitIndex { decimalBase *= 10 } return (self / decimalBase) % 10 } } 746381295[0] // returns 5 746381295[1] // returns 9 746381295[2] // returns 2 746381295[8] // returns 7 //如果该Int值没有足够的位数,即下标越界,那么上述实现的下标会返回0,因为它会在数字左边自动补0: 746381295[9] //returns 0, //即等同于: 0746381295[9] //1.6嵌套类型(Nested Types) //扩展可以向已有的类、结构体和枚举添加新的嵌套类型: extension Character { enum Kind1 { case Vowel,Consonant,Other } var kind: Kind1 { switch String(self).lowercaseString { case "a","e","i","o","u": return .Vowel case "b","c","d","f","g","h","j","k","l","m","n","p","q","r","s","t","v","w","x","y","z": return .Consonant default: return .Other } } } //该例子向Character添加了新的嵌套枚举。这个名为Kind的枚举表示特定字符的类型。具体来说,就是表示一个标准的拉丁脚本中的字符是元音还是辅音(不考虑口语和地方变种),或者是其它类型。 // //这个类子还向Character添加了一个新的计算实例属性,即kind,用来返回合适的Kind枚举成员。 // //现在,这个嵌套枚举可以和一个Character值联合使用了: func printLetterKinds(word: String) { print("'\\(word)' is made up of the following kinds of letters:") for character in word.characters { switch character.kind { case .Vowel: print("vowel ") case .Consonant: print("consonant ") case .Other: print("other ") } } print("\n") } printLetterKinds("Hello") // 'Hello' is made up of the following kinds of letters: // consonant vowel consonant consonant vowel //函数printLetterKinds的输入是一个String值并对其字符进行迭代。在每次迭代过程中,考虑当前字符的kind计算属性,并打印出合适的类别描述。所以printLetterKinds就可以用来打印一个完整单词中所有字母的类型,正如上述单词"hello"所展示的。 // //注意:由于已知character.kind是Character.Kind型,所以Character.Kind中的所有成员值都可以使用switch语句里的形式简写,比如使用 .Vowel代替Character.Kind.Vowel@H_323_502@

猜你在找的Swift相关文章