Swift(结构与枚举,继承与多态,协议,字符串,集合类型) g
上一回http://www.jianshu.com/p/fe204df5e1f5
------结构与枚举
---结构
红色重点
class RPoint{
var x:Int
var y:Int
init(x:Int, y:Int){
self.x=x
self.y=y
}
deinit{
print("clean up")
}
}
struct SPoint{
var x:Int
var y:Int
var z:RPoint
}
var rp=RPoint(x:10, y:20)
//struct有默认按成员初始化器
var sp1=SPoint(x:10, y:20, z: RPoint(x: 100,y: 200))
var sp2=sp1
print(" \(sp1.x), \(sp1.y), \(sp1.z.x), \(sp1.z.y)")
print(" \(sp2.x), \(sp2.y), \(sp2.z.x), \(sp2.z.y)")
sp1.x+=10
sp1.y+=10
sp1.z.x+=10
sp1.z.y+=10
//会发现2的x,y没有随1的x,y改变而改变.
//但是2zx,zy就随着1的zx,zy 改变而改变.
//随意关于数据修改方面 不要在struct内定义引用类型
print(" \(sp1.x), \(sp1.y), \(sp1.z.x), \(sp1.z.y)")
print(" \(sp2.x), \(sp2.y), \(sp2.z.x), \(sp2.z.y)")
---结构与类的相同点与不同点(struct VS Class)
---枚举类型
//定义枚举类型
enum Color {
case Red
case Green
case Blue
}
enum ComplexColor{
case Red,Green,Blue,Alpha
}
//枚举的使用
var c1=Color.Red
var c2:Color
c2 = Color.Green
c1 = .Blue
var c3=c1
//全局函数使用枚举类型
func print(color: Color){
//switch类型要包含所有枚举类型
switch color {
case .Red:
print("Red Color!")
case .Green:
print("Green Color!")
case .Blue:
print("Blue Color!")
//default:(可以省略剩余的)
//print("剩余的")
}
}
//基本属于用于计算性
//指定原始类型
enum WeekDay: Int{//类型只能是字符,字符串,整数.或者浮点数
case Monday=1, Tuesday, Wednesday,Thursday, Friday, Saturday, Sunday
}
var day: WeekDay?
day = WeekDay(rawValue: 7)
var data=WeekDay.Saturday.rawValue
class Point{
var x=0
var y=0
init(x:Int, y:Int){
self.x=x
self.y=y
}
}
//枚举关联值
enum Position{
case Number(Point)
case Name(String)
}
var p1=Position.Number(Point(x: 123,y: 588))
var p2=Position.Name("Shanghai People's Square")
func print(position: Position){
switch position {
case .Number(let number):
print("[\(number.x), \(number.y)]")
case .Name(let name):
print(name)
}
}
print(p1)
print(p2)
------继承与多态
Snip20160515_25.pngstruct Point{
var x=0
var y=0
}
class Shape{
var no=0
func move() {
print("NO: \(no) Shape.move")
}
}
class Rectangle: Shape{
var leftUp=Point()
var width=0
var height=0
}
class Circle: Shape{
var center=Point()
var radius=0
}
func process(shape: Shape){
shape.no += 1
shape.move()
}
var r1=Rectangle()
var c1=Circle()
//成员复用
r1.no += 1
r1.move()
c1.no += 1
c1.move()
//类型抽象
process(c1)
process(r1)
var s:Shape
s=c1
s=r1
class Shape{
var no=0
//0x000340
final func show(){
print("Shape.show")
}
//0x000640
func move() {
print("Shape.move")
}
}
//override多态定义
//Rectangle 重写
class Rectangle: Shape{
override var no: Int {
get{
print("Rectangle.no.get()")
return super.no
}
set{
print("Rectangle.no.set()")
super.no=newValue
}
}
//0x000880
override func move() {
print("Rectangle.move")
}
}
//override多态定义
class Circle: Shape{
override func move() {
print("Circle.move")
}
}
func process(shape: Shape){
shape.no += 1
shape.move() //根据实际类型来调用
}
//变量有双重身份:
//1. 声明类型
//2. 实际类型
var sp: Shape
sp=Shape()
sp.move() // JMP GetVirtualMethod(sp) 二次指针间接运算
sp.show() // JMP 0x000340
//换实际类型
sp=Rectangle()
sp.move() // JMP GetVirtualMethod(sp) 二次指针间接运算
process(sp)
sp=Circle()
sp.move()
process(sp)
class Base{
var data1:Int
init(){
data1=100
print("\(data1)")
print("Base.init")
}
deinit{
print("Base.deinit")
}
}
class Sub1: Base{
var data2=200
//自动继承base的初始化器
//自动继承父类的析构器
}
class Sub2: Base{
var data2=200
//不继承Base初始化器,使用自己的初始化器
//override 初始化器的原型一致的时候使用
override init(){
super.init()//手动调用父的初始化器,还有想调用父类的属性也要手动
//不调用回自动生成
print("\(data1), \(data2)")
print("Sub.init")
}
deinit{
//子类调用完 会自动调用父类的析构器 super.deinit
print("Sub.deinit")
}
}
func process(){
var a:Base
a=Base()
print("----------")
var b:Base
b=Sub1()
print("----------")
var c:Base
c=Sub2()
print("----------")
}
process()
------协议
协议很少使用到静态属性
struct 实例方法要加上mutating
---协议变量的内存模型遵从实际类型的内存模型
引用类型传值.拷贝采用传引用方式
值类型传值.采用拷贝传值方式
---检查协议类型
使用is检查类型是否实现了协议
使用as?和as!将类型下追溯转型为协议
protocol AProtocol {
func display()
}
class Base {
var no = 0
}
class sub: Base,AProtocol {
func display() {
print(no)
}
}
//Compilt-time Type = 编译时类型,声明类型
var item1 , item2:Base
//Runtime Type = 运行时类型,实际类型
item1 = Base()
item2 = sub()
if (item1 is AProtocol){
print("item1是AProtocol的基类")
}
if (item2 is AProtocol){
print("item2是AProtocol的基类")
}
var item3:AProtocol?
var item4=sub()
//item3 = item1//不能写,因为var item3:AProtocol? 而item1 :base
item3 = item1 as? AProtocol //as?多态转型
item3 = item2 as? AProtocol
item3 = item4
---协议中的属性
--协议可以定义只读属性,也可以定义读写属性
--协议可以定义实例属性,也可以定义类型属性
--协议中只能定义变量属性,不能定义常量属性
--实现协议并不要求实现为储存属性还是计算属性
---协议中的方法
-协议可以定义实例方法,也可以定义类型方法
--协议中方法不能定义参数默认值
--针对值类型的mutating协议方法
-值类型(struct and enum )实现的实例方法如果要更改实例本身,需要在协议方法的定义中标明mutating关键字,同时在方法实现时也添加mutating关键字
-添加了mutating的协议方法,对类的实现方法无影响.在类内实现mutating协议方法时,无需再添加mutating关键字
---协议中的初始化器
--协议可以定义初始化器,但是不能定义析构器
--当class中实现协议定义的初始化器时候,需要添加required关键字
-标明子类也需要提供该初始化器
-如果定义为final类就不需要required关键字
--协议可以定义可失败的初始化器 init?,具体实现时可以失败,也可以非失败
----更多协议形式
---协议继承
--协议可以继承一个或者多个协议
--实现子协议类型,也必须实现父类协议中约定成员
---协议组合
--可以实现组合协议类型,使用protocol<A,B,.....>来组合多个协议
--显示组合协议类型,必须实现组合协议中的每一个协议.
--组合协议是一个临时类型
---可选协议
--协议的某些成员可以定义为optional ,不必实现
--可选协议只能应用于class,不能引用于struct和enumeration
--可选协议必须表用@objc特性
@import Foundation
//协议继承
protocol AProtocol{
func display()
}
//B协议继承A协议
protocol BProtocol:AProtocol {
func invoke ()
}
protocol CProtocol {
func excute ()
}
//ClassA BProtocol 要实现A协议的display也要同时B协议invoke
class ClassA: BProtocol {
func display() {
print("dispaly")
}
func invoke() {
print("invoke")
}
}
class ClassB: AProtocol,CProtocol {
func display() {
print("dispaly")
}
func excute() {
print("excute")
}
}
//协议组合,临时类型
func process (item:protocol<AProtocol,CProtocol>){
//可以调用a.c协议其中一个
item.display()
item.excute()
}
var b = ClassB()
process(b)
@objc protocol DProtocol{
optional var discription:String{get}
optional func move()
}
// DProtocol成员里面添加optional ClassC 就不用DProtocol实现成员
class ClassC: DProtocol {
}
------字符串
//String是一个Struct,但内部包含一个指向堆上的"内容指针",其指向的对象存放真正的字符串内容
var srt1:String = "Hello"
var srt2 = "Hello,World"
var srt3 = "I am programming in Swift"
print(sizeofValue(srt1))
print(strideofValue(srt1))
print(sizeofValue(srt2))
print(strideofValue(srt2))
print(sizeofValue(srt3))
print(strideofValue(srt3))
import Foundation
/*
-----------------------------
*/
//使用var和let控制字符串的可变性
var str1 = "Hello"
let str2 = ",Swoft"
//str1+=str2
//枚举字符
for item in str1.characters{
print(item)
}
for index in str1.characters.indices{
print(str1[index])
}
print(str1.characters.count)
print(str1[str1.startIndex])
//不能提出某个字符
//str1[1]
//起始字母
print(str1[str1.startIndex])
//起始字母的下一个字符
print(str1[str1.startIndex.successor()])
//最后一个字符
print(str1[str1.endIndex.predecessor()])
//起始字母往后数第四个距离的子午
let index = str1.startIndex.advancedBy(4)
print(str1[index])
/*
-----------------------------
*/
//链接字符串
//1.用appendContentsOf
str1.appendContentsOf(",World")
//2.+ 和+=号
var str3 = str1+str2
str1+=str2
//3.用append方法
var char:Character="!"
str1.append(char)
//字符转义
let heart = "\u{2665}"
print(heart)
//\t空出一个位置
let work = "\tHello"
print(work)
//插值
var x=100
var y=200
var text = "[\(x),\(y)]"
//字符串比较
var text1 = "Swift"
var text2 = "Swift"
var text3 = "swift"
print(text1==text2)
print(text1==text3)
import Foundation
var str1 = "Hello"
var str2 = str1
str1.appendContentsOf(",Work")
print(str1)
print(str2)
缓存容量与增长
import Foundation
var str = "Hello"
print(str.characters.count)
print(str)
//分配好capacity
str.reserveCapacity(10000)
print(str.characters.count)
------集合类
----数组
//数组声明与实例化
var array1 = [1,2,3,4,5]
var array2 :[Int]
var array3:Array<Int>
//--------------------
class MyClass{
init(){
print("MyClass.init")
}
deinit{
print("MyClass.deinit")
}
}
var objectArray = [MyClass]()
for _ in 1...5{
objectArray.append(MyClass())
}
print(objectArray.count)
////清空元素
objectArray.removeAll()
//变量数组和常量数组
var array5=[1,2,3]
let array6=[1,2,3]
array5.append(40)
array5[3]=4
print(array5)
//数组操作
for item in array5{
print(item)
}
for(index,value) in array5.enumerate(){
print("\(index),\(value)")
}
for index in 0..<array5.count {
print(array5[index])
}
var array7=array5+array6
array5+=[5,6,7]
print(array5.count)
array5[4...6]=[6,7,8]
print(array5)
//加入元素
array5.insert(5, atIndex: 4)//代价大
print(array5)
//删除元素
array5.removeAtIndex(7)//代价大
print(array5)
//缓存容量
var array8=[1,2,3]
array8.reserveCapacity(120)
for index in 4...100{
array8.append(index)
}
//打印口可以清晰看见capacity 的呈倍数上次 最好是一开始定义好capacity的大小
print("\(array8.count).\(array8.capacity)")
Snip20160515_19.png
//copy-0n-write
var array9 = array1
//未修改前array9 与array1 同一个指针
array1[0]=10
array1.append(20)
//修改后array9与array1不同一个指针
print(array1)
print(array9)
----集合
var words = Set<String>()
//不能有重复元素
words.insert("Hello")
words.insert("Swift")
words.insert("Language")
words.insert("Hello")
words.count
words=[]
words.count
var cities1:Set<String>
cities1=["Shanghai"]
for city in cities1.sort(){
print(city)
}
cities1.count
//contains是否含有相同元素
cities1.contains("New York")
var ciries2:Set = ["New York","Shanghai"]
print(cities1.isSubsetOf(ciries2))
//remove清楚元素
cities1.remove("Shanghai")
//是否相等
print(cities1==ciries2)
//2是否含有1的元素
print(cities1.isSubsetOf(ciries2))
----数组
var dictionary1 = [String:Int]()
var dictionary2 :Dictionary<String,Int>
dictionary2=["jason":36,"tom":31,"Marty":44]
for(name,age) in dictionary2{
print("the age of \(name) is:\(age)")
}
for name in dictionary2.keys{
print(name)
}
for value in dictionary2.keys{
print(value)
}
dictionary2.count
//修改元素, 一下两个性质是一样
dictionary2["tom"]=32
dictionary2.updateValue(33, forKey: "tom")
//添加
dictionary2["julie"]=28
dictionary2.count
//shan
dictionary2["Marty"]=nil
dictionary2.removeValueForKey("tom")
dictionary2.count