swift3.0 基礎(chǔ)知識(shí)點(diǎn)

importUIKit

classViewController:UITabBarController{

enumDayssofaWeek {//星期

caseSunday

caseMonday

caseTUESDAY

caseWEDNESDAY

caseThursday

caseFriday

caseSaturday

}

enumStudent {//學(xué)生

caseName(String)

caseMark(Int, Int, Int)

funcstudentSSS(a:Int, b:Int) ->Int{

returna+b

}

}

structMarkStruct {//結(jié)構(gòu)體

varEnglish:Int

varChines:Int

varMath:Int

funcmarkStrDid(English:Int, Math:Int) ->Int{

returnEnglish+Math

}

// (1) mutating可以從方法內(nèi)部改變它的屬性镐捧;并且它做的任何改變?cè)诜椒ńY(jié)束時(shí)還會(huì)保留在原始結(jié)構(gòu)中

mutatingfuncsubMarks(english:Int, math:Int)

->Int{//

self.English += english//在可變方法中給self賦值:可變方法能夠賦給隱含屬性self一個(gè)全新的實(shí)例。

Math += math//改變它的屬性,并且它做的任何改變?cè)诜椒ńY(jié)束時(shí)還會(huì)保留在原始結(jié)構(gòu)中

print("英語(yǔ):",self.English,self.Math)

returnself.English-self.Math

}

// (2)方法的func關(guān)鍵字之前加上關(guān)鍵字static库说。類可能會(huì)用關(guān)鍵字class來(lái)允許子類重寫父類的實(shí)現(xiàn)方法

staticfuncminMarks(english:Int, math:Int)

->Int{

ifenglish < math {

returnenglish

}else{

returnmath

}

}

// (3)下標(biāo)腳本:? subscript

subscript(index:Int) ->Int{

returnEnglish / index

}

// (4)下標(biāo)腳本的重載

subscript(row:Int, columns:Int) ->Int{

get{

return(row * columns) + columns

}

set{

}

}

}

overridefuncviewDidLoad() {

super.viewDidLoad()

// Do any additional setup after loading the view, typically from a nib.

self.view.backgroundColor = UIColor.grayColor()

//? ? ? ? let nav1 = UINavigationController.init(rootViewController: FirstViewController)

//? ? ? ? let nav2 = UINavigationController.init(rootViewController: FirstViewController)

//

//? ? ? ? self.viewControllers:[nav1, nav2]

//

// (1)Swift引入

// import語(yǔ)句引入OC框架(或C庫(kù))到swift程序中,

// swift應(yīng)用中可以簡(jiǎn)單額的混入C掂墓、C++語(yǔ)言代碼护戳,

// (2)swift標(biāo)記: swift程序由多種標(biāo)記組成,標(biāo)記可以是單詞绊率、標(biāo)識(shí)符谨敛、常量、字符串或符號(hào)即舌,

print("test!")//標(biāo)記是:?jiǎn)卧~佣盒、符號(hào)

// (3)注釋

//與C語(yǔ)言注釋極其相似,不同之處是多行注釋可以嵌套在其他的多行注釋的內(nèi)部

//單行注釋:? //多行注釋:

/* */

/*

/*嵌套注釋*/

*/

// (4)分號(hào):不要求每行語(yǔ)句的結(jié)尾處使用分號(hào)(;)顽聂,但是在同一行書(shū)寫多條語(yǔ)句時(shí)要用分號(hào)隔開(kāi)

print("分號(hào);;;;")

let_fenhao:NSString="分號(hào)";

print(_fenhao)

// (5)標(biāo)識(shí)符

//標(biāo)識(shí)符就是給常量肥惭、變量盯仪、方法、函數(shù)蜜葱、枚舉全景、結(jié)構(gòu)體、類牵囤、協(xié)議爸黄、等指定的名字

//命名規(guī)則:可由下劃線、數(shù)字揭鳞、字母組成炕贵,不可以數(shù)字開(kāi)頭,區(qū)分大小寫;若非要以關(guān)鍵字作為標(biāo)識(shí)符需要在關(guān)鍵字前后添加重音符號(hào)(')

// (6)關(guān)鍵字

/*關(guān)鍵字類似于標(biāo)識(shí)符的保留字符序列野崇,除非用重音符號(hào)(')將其括起來(lái)称开,不然不可作為標(biāo)識(shí)符。關(guān)鍵字是對(duì)編譯器具有特殊意義的預(yù)定義保留標(biāo)識(shí)符乓梨。

{

與聲明有關(guān)的關(guān)鍵字: calss func let public typealias deinit import operator static var enum init private struct

extension internal protocol subscript

與語(yǔ)句有關(guān)的關(guān)鍵字: if else ? for in break continue? return ? do while switch case where? default? fallthrough

表達(dá)式和類型關(guān)鍵字: is true fale nil as? self super dynamic _COLUMN_? _LINE_? _FILE_? _FUNCTION_

在特定上下文中使用的關(guān)鍵字:

associativityconveniencedynamicdidSet

finalgetinfixinout

lazyleftmutatingnone

nonmutatingoptionaloverridepostfix

precedenceprefixProtocolrequired

rightsetTypeunowned

weakwillSet

}

*/

// (7)swift空格:在swift中鳖轰,運(yùn)算符不能直接跟在變量或常量的后面

//錯(cuò)誤例:let aaa= "12344"

let aaa = 1 + 2(1 +語(yǔ)句到此結(jié)束,2是下一個(gè)語(yǔ)句)

letaaa =1+2;//規(guī)范編碼推薦使用

letbbb =2+3//也ok

print(aaa,bbb)

// (8)swift字面量:指特定的數(shù)字扶镀、字符串或布爾值這樣蕴侣,能夠直接了當(dāng)?shù)闹赋鲎约旱念愋筒樽兞窟M(jìn)行賦值

42//整形字面量

3.14159//浮點(diǎn)型字面量

"hellow swift!"http://字符串字面量

true//布爾值字面量

//

//

// (1)常量聲明(使用關(guān)鍵字let聲明)

// let constantName =

letconstInt =42

letconstFloat =2.11

letconstString ="string"

print(constInt, constFloat, constString)

// (2)類型標(biāo)注(添加類型標(biāo)注,需要在常量或者變量名后面加上一個(gè)冒號(hào)和空格臭觉,然后加上類型名稱)

// var constantName: =

letaaInt:Int=2

letaaFloat:Float=3.1415926

print(aaInt,"\n", aaFloat)

// (3)常量命名(由字母昆雀,數(shù)字和下劃線組成,以字母或下劃線開(kāi)始,也可以使用簡(jiǎn)單的Unicode字符)

let_const ="hello swift!"

let你好="你好世界"

print(_const,"\n",你好)

print("\(_const) ......\(你好)")

// (4)常量輸出

//變量和常量可以使用print(swift

2將print替換了println)函數(shù)來(lái)輸出。

//字符串中可以使用括號(hào)與反斜線來(lái)插入常量

letprintName ="菜鳥(niǎo)教程"

letprintName2 ="http://www.runoob.com"

print("\(printName)的官網(wǎng)地址為:\(printName2)")

//

//

//變量是一種使用方便的占位符胧谈,用于引用計(jì)算機(jī)內(nèi)存地址忆肾。

// Swift每個(gè)變量都指定了特定的類型,該類型決定了變量占用內(nèi)存的大小菱肖,不同的數(shù)據(jù)類型也決定可存儲(chǔ)值的范圍客冈。

// (1)變量聲明

//變量聲明的意思是告訴編譯器在內(nèi)存中的哪個(gè)位置為變量創(chuàng)建多大的存儲(chǔ)空間。

//使用var關(guān)鍵字聲明

// var variableName =

varvarA =42

varvarB:Float

varB =3.1415926

varA +=1

print(varA, varB)

// (2)變量命名

//由字母稳强、數(shù)字场仲、下劃線組成,以字母或下劃線開(kāi)始退疫,也可以使用簡(jiǎn)單的Unicode字符

var_varA ="hellow swift!"

_varA ="ni hao!"

print(_varA)

// (3)變量輸出

//變量和常量可以使用print(swift

2將print替換了println)函數(shù)來(lái)輸出渠缕。

//字符串中可以使用括號(hào)與反斜線來(lái)插入常量

var_varB:NSString="菜鳥(niǎo)教程"

_varB ="菜鳥(niǎo)教程"

var_varC:NSString="http://www.runoob.com"

_varC =" http://www.runoob.com "

print("\(_varB)的官網(wǎng)是:\(_varC)")

//

//

//使用數(shù)據(jù)類型存儲(chǔ)不同的信息

// (1)內(nèi)置數(shù)據(jù)類型

//常用數(shù)據(jù)類型:Int ? UInt浮點(diǎn)數(shù)布爾值字符串字符可選類型

/**

Int ? :長(zhǎng)度與當(dāng)前平臺(tái)的原生字長(zhǎng)相同,在32(64)位平臺(tái)上,Int和Int32(Int64)長(zhǎng)度相同褒繁,

在32位平臺(tái)上亦鳞,Int可以存儲(chǔ)的整數(shù)范圍-2,147,438,648~2,147,483,647

UInt? :無(wú)符號(hào)整形,

浮點(diǎn)數(shù):? {

double : 64位浮點(diǎn)數(shù),最少15位

float? : 32位浮點(diǎn)數(shù),最少6位

}

布爾值:? true , false

字符串:字符串是字符的序列集合"hellow swift!"

字符:指單個(gè)字母,“C”

可選類型:使用可選類型(optionals)來(lái)處理值可能缺失的情況燕差,可選類型表示有值或沒(méi)值

*/

// (2)數(shù)值范圍

/**

類型大性馑瘛(字節(jié))區(qū)間值

Int8? ? ? ? ? 1字節(jié)-127 ~ 127

UInt8 ? ? ? ? 1字節(jié)0 ~ 255

Int32 ? ? ? ? 4字節(jié)-2^31 ~ 2^31

UInt32? ? ? ? 4字節(jié)0 ~ 2^32

Int64 ? ? ? ? 8字節(jié)-9223372036854775808 ~ 9223372036854775807

UInt64? ? ? ? 8字節(jié)0 ~ 18446744073709551615

Float ? ? ? ? 4字節(jié)1.2E-38 ~ 3.4E+38 (~6 digits)

Double? ? ? ? 8字節(jié)2.3E-308 ~ 1.7E+308 (~15 digits)

*/

// (3)類型別名:類型別名對(duì)當(dāng)前的類型定義了另一個(gè)名字,類型別名通過(guò)使用typealias關(guān)鍵字來(lái)定義

//語(yǔ)法格式typealias newsname = type

typealiaszhengxing =Int

letcccInt:zhengxing=3

print(cccInt)

// (4)類型安全:會(huì)在編譯代碼時(shí)進(jìn)行類型檢查(type checks)徒探,把不匹配的類型標(biāo)記為錯(cuò)誤瓦呼,可以在開(kāi)發(fā)時(shí)盡早發(fā)現(xiàn)修復(fù)錯(cuò)誤

varvarCC =42

// varCC = "hellow swift!"? //報(bào)錯(cuò):cannot assign value of type 'String' to type 'Int'

varCC =43

print(varCC)

// (5)類型推斷:如果沒(méi)有顯式的指定類型,swift會(huì)使用推斷類型(type

inference)來(lái)選擇適合的類型

letddInt =42// ddInt會(huì)被推斷為Int類型

letpi =3.14159// pi會(huì)被推斷為double類型测暗,浮點(diǎn)數(shù)的類型會(huì)推斷為double,不是float

letpipi =3+0.14159;//表達(dá)式中同時(shí)出現(xiàn)整形和浮點(diǎn)數(shù)央串,會(huì)被推斷為double類型

print(ddInt,pi,pipi)

//

//

//所謂字面量,就是指特定的數(shù)字碗啄、字符串或者布爾值這樣质和,能夠直接的指出自己的類型并為變量進(jìn)行賦值的值

// (1)整型字面量:可以是十進(jìn)制、八進(jìn)制稚字、二進(jìn)制或十六進(jìn)制常量侦另,二進(jìn)制前綴0b,八進(jìn)制前綴0o,十六進(jìn)制前綴0x

letdecimalInteger =17//17十進(jìn)制

letbinaryInteger =0b10001//17二進(jìn)制

letoctalInteger =0o021//17八進(jìn)制

lethexadecimalInteger =0x11//17十六進(jìn)制

print(decimalInteger,binaryInteger,octalInteger,hexadecimalInteger)

// (2)浮點(diǎn)型字面量:有整數(shù)部分,小數(shù)點(diǎn)尉共,小數(shù)部分及指數(shù)部分

//浮點(diǎn)型字面量的默認(rèn)推到類型為Double,表示64位浮點(diǎn)數(shù)

//十進(jìn)制指數(shù): ? 1.25e2表示1.25*10^2 , ? 1.25e-2表示1.25*10^-2(e或E)10^

//十六進(jìn)制: ? ? 0xFp2表示15*2^2? , ? ? (p或P) 2^

letdecimalDouble =12.1875//十進(jìn)制浮點(diǎn)型字面量

letexpontDouble =1.21875e1//十進(jìn)制浮點(diǎn)型字面量

lethexadecimalDouble =0xC.3p0//十六進(jìn)制浮點(diǎn)型字面量

print(decimalDouble,expontDouble,hexadecimalDouble)

// (3)字符串型字面量:由被包在雙引號(hào)中的一串字符串組成"charaters"

//字符型字面量中不能包含未轉(zhuǎn)義的雙引號(hào)(“)弃锐、未轉(zhuǎn)義的反斜線(\)袄友、回車符或換行符

/**

轉(zhuǎn)移字符含義

\0空字符

\\反斜線\

\b退格(BS),將當(dāng)前位置移到前一列

\f換頁(yè)(FF)霹菊,將當(dāng)前位置移到下頁(yè)開(kāi)頭

\n換行符

\r回車符

\t水平制表符

\v垂直制表符

\'單引號(hào)

\"雙引號(hào)

\000 ? ? ? ? ? ? ? 1到3位八進(jìn)制數(shù)所代表的任意字符

\xhh...? ? ? ? ? ? 1到2位十六進(jìn)制所代表的任意字符

*/

letstringL ="Hello\tWorld\n\n菜鳥(niǎo)教程官網(wǎng):\'http://www.runoob.com\'"

print(stringL)

/**輸出

HelloWorld

菜鳥(niǎo)教程官網(wǎng):'http://www.runoob.com'

*/

// (4)布爾型字面量:默認(rèn)類型是Bool

//布爾值字面量有三個(gè)值剧蚣,是swift的保留關(guān)鍵字:true:表示真,false:表示假旋廷,nil:表示沒(méi)有值

//

//

// swift的可選(optional)類型鸠按,用于處理值缺失的情況,swift語(yǔ)言定義后綴問(wèn)號(hào)?作為命名類型optional的簡(jiǎn)寫饶碘,例如以下兩種聲明相等

/**

var optionalInteger: Int?

var optionalInteger: Optional

*/

//聲明一個(gè)可選類型時(shí)目尖,要確保用括號(hào)給?操作符一個(gè)適合的范圍,例如扎运,聲明可選整數(shù)數(shù)組:(Int[])?,不是Int[]?

//聲明一個(gè)可選變量或者可選屬性的時(shí)候沒(méi)有提供初始值仑氛,它的值默認(rèn)為nil

//如果一個(gè)可選類型的實(shí)例包含一個(gè)值科乎,可以用后綴操作符!來(lái)訪問(wèn)這個(gè)值,

//使用操作符鸠珠!去獲取值為nil的可選變量會(huì)有運(yùn)行時(shí)錯(cuò)誤,可以用可選鏈接和可選綁定選擇性執(zhí)行可選表達(dá)式上的操作。如果值為nil沐祷,任何操作都不會(huì)執(zhí)行脚仔,也不會(huì)有運(yùn)行報(bào)錯(cuò)。

/**

optionalInteger = 42

optionalInteger!? //42

var optionalInteger: Int?

optionalInteger = 42

print(optionalInteger!)

*/

letccString:String? =nil

ifccString !=nil{

print(ccString)

}else{

print("字符串為nil")

}

//可選類型類似于OC中的指針的nil值,但是nil只針對(duì)類(class)有用花吟,而可選類型對(duì)所有類型都可用秸歧,且更安全。

// (1)強(qiáng)制解析:當(dāng)你確定可選類型確實(shí)包含值之后示辈,你可以在可選的名字后面加一個(gè)感嘆號(hào)(!)來(lái)獲取值寥茫。這個(gè)感嘆號(hào)表示"我知道這個(gè)可選有值,請(qǐng)使用它矾麻。"這被稱為可選值的強(qiáng)制解析(forced

unwrapping)

varcccStr:String?

cccStr ="hellow swift!"

ifcccStr !=nil{

print(cccStr!,"\n",cccStr)//強(qiáng)制解析

}else{

print("字符串為nil")

}

/**輸出

hellow swift!? ? //強(qiáng)制解析結(jié)果

Optional("hellow swift!")

注意:

使用!來(lái)獲取一個(gè)不存在的可選值會(huì)導(dǎo)致運(yùn)行時(shí)錯(cuò)誤纱耻。使用!來(lái)強(qiáng)制解析值之前,一定要確定可選包含一個(gè)非nil的值险耀。

*/

// (2)自動(dòng)解析:你可以在聲明可選變量時(shí)使用感嘆號(hào)(!)替換問(wèn)號(hào)(?)弄喘。這樣可選變量在使用時(shí)就不需要再加一個(gè)感嘆號(hào)(!)來(lái)獲取值,它會(huì)自動(dòng)解析

varccccString:String!

ccccString ="自動(dòng)解析甩牺。蘑志。。";

ifccccString !=nil{

print(ccccString)

}else{

print("字符串為nil")

}

/**輸出

自動(dòng)解析贬派。急但。。

*/

// (3)可選綁定:使用可選綁定(optional binding)來(lái)判斷可選類型是否包含值搞乏,如果包含就把值賦給一個(gè)臨時(shí)常量或者變量波桩。可選綁定可以用在if和while語(yǔ)句中來(lái)對(duì)可選類型的值進(jìn)行判斷并把值賦給一個(gè)常量或者變量请敦。

/**

if let constantName = someOptional {

statements

}

*/

varcccccString:String?

cccccString ="kexuanbangding...."

ifletCCCCString = cccccString {

print(CCCCString)

}else{

print("字符串沒(méi)有值");

}

//

//

//運(yùn)算符是一個(gè)符號(hào)镐躲,用于告訴編譯器執(zhí)行一個(gè)數(shù)學(xué)或邏輯運(yùn)算。

/**

算數(shù)運(yùn)算符: + ? - ? * ? / ? % ? ++? --

比較運(yùn)算符號(hào): ==? ? != ? >? ? <? ? >=? ? <=? ? (結(jié)果為true,

false)

邏輯運(yùn)算符: &&? ? ? ||? ? ? ! ? ? ? ? (結(jié)果為true, false)

位運(yùn)算符:位運(yùn)算符用來(lái)對(duì)二進(jìn)制位進(jìn)行操作侍筛,~ ? & ? | ? ^ ? <<? ? >>

&(按位與萤皂,都為1時(shí)才為1,其他為0)

|(按位或匣椰,有一個(gè)為1就為1)^(按位異或裆熙,相同為0,不同為1)

~(按位取反) ? ? <<(按位左移窝爪,將操作數(shù)的所有位向左移指定的位數(shù)弛车,空位用0補(bǔ)充)

>>(按位右移,)

賦值運(yùn)算符: = ? += ? -= ? *=? ? /=? %=? <<= ? >>= ? &=? ? ^=? ? |=

區(qū)間運(yùn)算符:閉區(qū)間運(yùn)算符(a...b)半開(kāi)區(qū)間運(yùn)算符(a...

其他運(yùn)算符: swift提供了其他類型的的運(yùn)算符蒲每,如一元纷跛、二元和三元運(yùn)算符.

*/

//區(qū)間運(yùn)算符

print("閉區(qū)間運(yùn)算符:")

forindexin1...5{

print("\(index) * 2 =\(index

*2)")

}

print("半開(kāi)區(qū)間運(yùn)算符:")

forindexin1..<5{

print("\(index) * 3 =\(index

*3)")

}

//運(yùn)算符優(yōu)先級(jí)

/**

指針最優(yōu),單目運(yùn)算優(yōu)于雙目運(yùn)算邀杏。如正負(fù)號(hào)贫奠。

先乘除(模)唬血,后加減。

先算術(shù)運(yùn)算唤崭,后移位運(yùn)算拷恨,最后位運(yùn)算。請(qǐng)?zhí)貏e注意:1 << 3 + 2 & 7等價(jià)于(1 << (3

+ 2))&7

邏輯運(yùn)算最后計(jì)算

*/

//

//

/**條件語(yǔ)句

if語(yǔ)句

if...else語(yǔ)句

if...else if...else語(yǔ)句

內(nèi)嵌if語(yǔ)句

switch語(yǔ)句

? :運(yùn)算符

*/

//

/**循環(huán)類型

for-in

for循環(huán)

while循環(huán)

repeat...while循環(huán):類似while語(yǔ)句區(qū)別在于判斷循環(huán)條件之前谢肾,先執(zhí)行一次循環(huán)的代碼塊

*/

/**循環(huán)控制語(yǔ)句

continue語(yǔ)句

break語(yǔ)句

fallthrough語(yǔ)句:如果在一個(gè)case執(zhí)行完后腕侄,繼續(xù)執(zhí)行下面的case,需要使用fallthrough(貫穿)關(guān)鍵字

*/

//

//

// swift字符串是一系列字符的集合芦疏。例如"Hello, World!"這樣的有序的字符類型的值的集合冕杠,它的數(shù)據(jù)類型為String

// (1)創(chuàng)建字符串

//是有字符串字面量

letstringA ="hellow CJstring"

print(stringA)

// String實(shí)例化

letstringB = String("hellow shilihua...")

print(stringB)

// (2)空字符串

//可以使用空的字符串字面量賦值給變量或初始化一個(gè)String類的實(shí)例來(lái)初始值一個(gè)空的字符串∷彳睿可以使用字符串屬性isEmpty來(lái)判斷字符串是否為空:

letstringAA =""http://是有字符串字面量創(chuàng)建空字符串

ifstringAA.isEmpty {

print("stringAA is empty....")

}else{

print("stringAA is not empty...")

}

letstringBB = String()//實(shí)例化String類來(lái)創(chuàng)建空字符串

ifstringBB.isEmpty {

print("stringBB is empty....")

}else{

print("stringBB is not empty...")

}

// (3)字符串常量

//你可以將一個(gè)字符串賦值給一個(gè)變量或常量分预,變量是可修改的,常量是不可修改的薪捍。

varstringAAA ="stringAAA is mutable..."http:// stringAAA可被修改

stringAAA +="http://www.runoob.com"

print(stringAAA)

letstringBBB = String("stringBBB is can not mutable...")//

//? ? ? ? stringBBB += "http://www.runoob.com" ? //報(bào)錯(cuò):left

side of mutating operator isn't mutable:'stringBBB' is a 'let' constant

print(stringBBB)

// (4)字符串中插入值

//字符串插值是一種構(gòu)建新字符串的方式笼痹,可以在其中包含常量、變量酪穿、字面量和表達(dá)式凳干。您插入的字符串字面量的每一項(xiàng)都在以反斜線為前綴的圓括號(hào)中

letvarAaAA =20

letconstaAAA =100

letvarAaAAA:Float=20.0

letstringAaAA ="\(varAaAA)乘以\(constaAAA)等于\(varAaAAA

*100)"

print(stringAaAA)

// (5)字符串連接

//字符串可以通過(guò)+號(hào)來(lái)連接

letlianjieA ="連接A..."

letlianjieB ="連接B..."

letlianjieC = lianjieA + lianjieB;

print(lianjieC)

// (6)字符串長(zhǎng)度

// String.characters.count

letchangduA ="12345678"

print("字符串長(zhǎng)度為\(changduA.characters.count)")

// (7)字符串比較

//你可以使用==來(lái)比較兩個(gè)字符串是否相等

iflianjieA == lianjieB {

}else{

}

// (8)Unicode字符串

// Unicode是一個(gè)國(guó)際標(biāo)準(zhǔn),用于文本的編碼被济,Swift的String類型是基于Unicode建立的纺座。你可以循環(huán)迭代出字符串中UTF-8與UTF-16的編碼

letunicodeA ="你好嗎!"

print("UTF-8編碼:")

forcodeinunicodeA.utf8 {

print("\(code)","\n")

}

print("UTF-16編碼:")

forcodeinunicodeA.utf16 {

print("\(code)","\n")

}

// (9)字符串函數(shù)及運(yùn)算符

/**

isEmpty :判斷字符串是否為空,返回布爾值

hasPrefix(prefix: String) :檢查字符串是否擁有特定前綴

hasSuffix(suffix: String) :檢查字符串是否擁有特定后綴溉潭。

Int(String) :轉(zhuǎn)換字符串?dāng)?shù)字為整型

String.characters.count? :計(jì)算字符串的長(zhǎng)度

utf8? :您可以通過(guò)遍歷String的utf8屬性來(lái)訪問(wèn)它的UTF-8編碼

utf16? :您可以通過(guò)遍歷String的utf16屬性來(lái)訪問(wèn)它的UTF-16編碼

unicodeScalars :您可以通過(guò)遍歷String值的unicodeScalars屬性來(lái)訪問(wèn)它的Unicode標(biāo)量編碼

+? :連接兩個(gè)字符串,并返回一個(gè)新的字符串

+=? :連接操作符兩邊的字符串并將新字符串賦值給左邊的操作符變量

==? :判斷兩個(gè)字符串是否相等

<? :比較兩個(gè)字符串少欺,對(duì)兩個(gè)字符串的字母逐一比較

!=? :比較兩個(gè)字符串是否不相等

*/

ifCFStringHasPrefix(unicodeA,"你")

{

print("CFStringHasPrefix.....YES")

}else{

print("CFStringHasPrefix.....NO")

}

ifCFStringHasSuffix(unicodeA,"!") {

print("CFStringHasSuffix.....YES")

}else{

print("CFStringHasSuffix.....NO")

}

letzhuanhuanInt:Int! = Int(changduA)

print(zhuanhuanInt)

print("標(biāo)量編碼:")

forcodeinunicodeA.unicodeScalars {

print("\(code)","\n")

}

//

// Swift的字符是一個(gè)單一的字符字符串字面量喳瓣,數(shù)據(jù)類型為Character

letcharA:Character="A"

print(charA)

// (1)空字符變量: Swift中不能創(chuàng)建空的Character(字符)類型變量或常量

//? ? ? ? let charAA:Character = "" ? // ""被推斷為String類型

// (2)遍歷字符串中的字符

forcharin"hellow swift".characters {

print(char)

}

// (3)字符串連接字符

varcharAA:String="連接。赞别。畏陕。"

charAA.append(charA)

print(charAA)

//

// Swift數(shù)組使用有序列表存儲(chǔ)同一類型的多個(gè)值

// (1)創(chuàng)建數(shù)組

// var someArray = [SomeType]()

vararrayA = [String]()

vararrayB = [String](count:3,repeatedValue:"arrayB...? ")

vararrayC = [10,20,30]

// (2)訪問(wèn)數(shù)組:可以根據(jù)數(shù)組的索引來(lái)訪問(wèn)數(shù)組的元素var someVar = someArray[index]

varindexB = arrayB[0]

varindexC = arrayC[1]

indexB ="indexBBBB....."

indexC +=40

// (3)修改數(shù)組:可以使用append()方法或者賦值運(yùn)算符+=在數(shù)組末尾添加元素

arrayA.append("arrayA... ")

arrayA += [indexB]

arrayA += ["\(indexC)"]

arrayB[0] ="arrayBBBBB....."

// (3)遍歷數(shù)組:使用for-in循環(huán)來(lái)遍歷所有數(shù)組中的數(shù)據(jù)項(xiàng)

//同時(shí)需要每個(gè)數(shù)據(jù)項(xiàng)的值和索引值,可以使用String的enumerate()方法來(lái)進(jìn)行數(shù)組遍歷

foriteminarrayB {

print(item)

}

for(index, item)inarrayB.enumerate() {

print(index, item,"\n")

}

// (4)合并數(shù)組:使用加法操作符(+)來(lái)合并兩種已存在的相同類型數(shù)組

vararrayD = [String]()

arrayD = arrayA + arrayB

print("輸出arrayD : ", arrayD)

// (5)count屬性

print("arrayD的元素個(gè)數(shù)是:\(arrayD.count)")

// (6)isEmpty屬性

print("arrayD是否為空:\(arrayD.isEmpty)")

//

//字典:用來(lái)存儲(chǔ)無(wú)序的相同類型數(shù)據(jù)的集合,

// (1)創(chuàng)建字典:

/**

var someDict =? [KeyType: ValueType]()創(chuàng)建一個(gè)特定類型的空字典

*/

vardicA = [String: String]()

vardicB = [Int: String]()

dicA = ["a":"1","b":"2","c":"3"]

dicB = [0:"a1",1:"b2",2:"c3"]

print(dicA, dicB)

letdicC:[Int:String] = [5:"five...",6:"six...",0:"a1"]

print(dicC)

// (2)訪問(wèn)字典: ? var someVar = someDict[key]

letkeyA:String! = dicA["a"]

print(keyA)

// (3)修改字典:使用updateValue(forKey:)增加或更新字典的內(nèi)容仿滔。如果key不存在惠毁,則添加值,如果存在則修改key對(duì)應(yīng)的值

dicA.updateValue("d", forKey:"4")

dicA["a"] ="11111"

print(dicA)

// (4)移除Key-Value對(duì):可以使用removeValueForKey()方法來(lái)移除字典key-value對(duì)崎页。如果key存在該方法返回移除的值鞠绰,如果不存在返回nil

//可以通過(guò)指定鍵的值為nil來(lái)移除key-value(鍵-值)對(duì)

dicB.removeValueForKey(1)

dicB[0] =nil

print(dicB)

// (5)遍歷字典:

//? ? ? ? for (key, value) in dicB { ? //兩種都可以

for(key, value)indicB.enumerate() {

print("字典:key :\(key),

value:\(value)")

}

// (6)字典轉(zhuǎn)換為數(shù)組:可以提取字典的鍵值(key-value)對(duì),并轉(zhuǎn)換為獨(dú)立的數(shù)組

letdicKeyA = [String](dicA.keys)

letdicValueA = [String](dicA.values)

print("dicA的鍵key :\(dicKeyA)")

print("dicA的值Value :\(dicValueA)")

// (7)屬性: count , isEmpty

print("字典dicB的元素個(gè)數(shù):\(dicB.count)......")

print("字典dicB是否為空:\(dicB.isEmpty).....")

//

//

// Swift函數(shù)用來(lái)完成特定任務(wù)的獨(dú)立的代碼塊,使用一個(gè)統(tǒng)一的語(yǔ)法來(lái)表示簡(jiǎn)單的C語(yǔ)言風(fēng)格的函數(shù)到復(fù)雜的Objective-C語(yǔ)言風(fēng)格的方法

/**

函數(shù)聲明:告訴編譯器函數(shù)的名字飒焦,返回類型及參數(shù)蜈膨。

函數(shù)定義:提供了函數(shù)的實(shí)體屿笼。

*/

// Swift函數(shù)包含了參數(shù)類型及返回值類型

// (1)函數(shù)定義(2)函數(shù)調(diào)用

/**定義函數(shù)使用關(guān)鍵字func語(yǔ)法

func funcname(形參) -> returntype

{

Statement1

Statement2

……

Statement N

return parameters

}

*/

funcresetNickname(userName:String) ->String{//定義函數(shù)

varname:String! = userName

name.appendContentsOf("...........")

returnname

}

print(resetNickname("phoebe_zhang"))//調(diào)用

// (3)函數(shù)參數(shù):函數(shù)可以接受一個(gè)或者多個(gè)參數(shù),我們也可以使用元組(tuple)向函數(shù)傳遞一個(gè)或多個(gè)參數(shù)

funcrefreshDidView(model1:Int, model2:Int) ->Int{

returnmodel1 * model2

}

print(refreshDidView(3, model2:5))

// (4)不帶參數(shù)函數(shù)

/**語(yǔ)法

func funcname() -> datatype {

return datatype

}

*/

funcrefreshNoti() {

}

refreshNoti()

// (5)元組作為函數(shù)返回值:

//元組與數(shù)組類似翁巍,不同的是驴一,元組中的元素可以是任意類型,使用的是圓括號(hào),你可以用元組(tuple)類型讓多個(gè)值作為一個(gè)復(fù)合值從函數(shù)中返回

funcminMax(arrayA:[Int]) -> (minA:Int, maxA:Int)?

{

ifarrayA.isEmpty {

returnnil

}

varmin = arrayA[0]

varmax = arrayA[0]

foriteminarrayA {

ifitem < min {

min = item

}elseif(max < item) {

max = item

}

}

return(min, max)

}

letminArray:[Int] = [1,6,8,3,12,45,78,0]

letvalueArrayy = minMax(minArray)!

print("數(shù)組arrayA中min : ", valueArrayy.minA,"\n","數(shù)組arrayA中max: ", valueArrayy.maxA)

print("min :\(valueArrayy.minA) ,? max :\(valueArrayy.maxA)")

//可選元組類型如(Int, Int)?與元組包含可選類型如(Int?,

Int?)是不同的.可選的元組類型灶壶,整個(gè)元組是可選的肝断,而不只是元組中的每個(gè)元素值。

// (6)沒(méi)有返回值函數(shù):

funcreadMyName(myName:String) {

print(myName)

}

readMyName("phoebe_zhangxiaoping...")

// (7)函數(shù)參數(shù)名稱:函數(shù)參數(shù)都有一個(gè)外部參數(shù)名和一個(gè)局部參數(shù)名

/**

局部參數(shù)名稱:在函數(shù)內(nèi)部使用,(例如myName為局部參數(shù)名驰凛,只能在函數(shù)體內(nèi)使用

外部參數(shù)名稱:可以在局部參數(shù)名前指定外部參數(shù)名胸懈,中間以空格分隔,外部參數(shù)名用于在函數(shù)調(diào)用時(shí)傳遞給函數(shù)的參數(shù)

*/

funcreadName(name myName:String, nickName myNickmane:String) {

print(myName, myNickmane)

}

readName(name:"zhangxiaoping", nickName:"phoebe")

// (8)可變參數(shù):可變參數(shù)可以接受零個(gè)或多個(gè)值洒嗤。函數(shù)調(diào)用時(shí)箫荡,你可以用可變參數(shù)來(lái)指定函數(shù)參數(shù),其數(shù)量是不確定的

//可變參數(shù)通過(guò)在變量類型名后面加入(...)的方式來(lái)定義

funcreadNickName(yourNicknam:String...) {

print(yourNicknam)

}

readNickName("你的昵稱","Phoebe","nickname")//輸出:? ["你的昵稱", "Phoebe", "nickname"]

// (9)常量渔隶,變量及I/O參數(shù)

//一般默認(rèn)在函數(shù)中定義的參數(shù)都是常量參數(shù)羔挡,也就是這個(gè)參數(shù)你只可以查詢使用,不能改變它的值

//一般默認(rèn)的參數(shù)傳遞都是傳值調(diào)用的间唉,而不是傳引用绞灼。所以傳入的參數(shù)在函數(shù)內(nèi)改變,并不影響原來(lái)的那個(gè)參數(shù)呈野。傳入的只是這個(gè)參數(shù)的副本

/**

(* swift 3中要?jiǎng)h除此方法)? func? getName(var id:String)....... ? :如果想要聲明一個(gè)變量參數(shù)低矮,可以在前面加上var,這樣就可以改變這個(gè)參數(shù)的值了

inout關(guān)鍵字:? In-Out Parameters輸入輸出參數(shù),如果你想要一個(gè)函數(shù)可以修改參數(shù)的值被冒,且想要在這些修改在函數(shù)調(diào)用結(jié)束后仍然存在军掂,則定義為輸入輸出參數(shù)

*/

/** swift 3中將要?jiǎng)h除此方法

func addAB(var a:Int, var b:Int) {

a *= 2

b *= 2

print("\(a) * \(b) = \(a*b)")

}

addAB(10, b: 10)

*/

varinoutA =10

varinoutB =20

funcinoutAB( a:inoutInt, b:inoutInt)

{

a *=2

b *=2

letc = a + b

print("a*2 + b*2 =\(c)")

}

print("原始值:",inoutA, inoutB)

inoutAB(&inoutA, b: &inoutB)

print("改變后:", inoutA, inoutB)

// (10)函數(shù)類型及使用:每個(gè)函數(shù)都有種特定的函數(shù)類型,由函數(shù)的參數(shù)類型和返回類型組成

//使用函數(shù)類型:你可以定義一個(gè)類型為函數(shù)的常量或變量昨悼,并將適當(dāng)?shù)暮瘮?shù)賦值給它

/**

var addition: (Int, Int) -> Int = sum

解析:定義一個(gè)叫addition的變量蝗锥,參數(shù)與返回的類型均為Int,并讓這個(gè)新變量指向sum函數(shù)率触。

sum和addition有同樣的類型终议,所以以上操作是合法的

*/

funcsum(a:Int, b:Int) ->Int{

returna+b

}

letaddAABB:(Int,Int) ->Int= sum

print(addAABB(10,20))

// (11)函數(shù)類型作為參數(shù)類型、函數(shù)類型作為返回類型:

//可以將函數(shù)作為參數(shù)傳遞給另外一個(gè)參數(shù)

funcsubA(a:Int, b:Int) ->Int{

returna-b

}

// var subB:(Int, Int) -> Int = subA

letsubB = subA

print("20 - 10 = ", subB(20,b:10))

funcsubC(subA: (_a:Int,_b:Int)->Int, c:Int, d:Int) {

print("30 - 20 = ", subA(a: c, b: d))

}

subC(subA, c:30, d:20)

// (12)函數(shù)嵌套:函數(shù)嵌套指的是函數(shù)內(nèi)定義一個(gè)新的函數(shù)葱蝗,外部的函數(shù)可以調(diào)用函數(shù)內(nèi)定義的函數(shù)

funcnestA(a:Int, b:Int) ->Int{

funcnestB(c:Int)->Int{

returnc*2

}

letd = nestB(10)

print("d =\(d)")

returnnestB(a) + nestB(b)

}

lete = nestA(10, b:20)

print("eeeeeeee ======\(e)")

//

//

/**

它聲明在類中穴张,可以通過(guò)實(shí)例化類來(lái)訪問(wèn)它的值。

枚舉也可以定義構(gòu)造函數(shù)(initializers)來(lái)提供一個(gè)初始成員值两曼;可以在原始的實(shí)現(xiàn)基礎(chǔ)上擴(kuò)展它們的功能皂甘。

可以遵守協(xié)議(protocols)來(lái)提供標(biāo)準(zhǔn)的功能

enum enumname {

//枚舉定義放在這里

}

*注意: Swift的枚舉成員在被創(chuàng)建時(shí)不會(huì)被賦予一個(gè)默認(rèn)的整型值

*/

// (1)語(yǔ)法:

varweekDay = DayssofaWeek.WEDNESDAY

weekDay = .WEDNESDAY

switchweekDay {

case.Sunday:

print("周日")

case.WEDNESDAY:

print("周三")

default:

print("周六")

}

// (2)相關(guān)值:以下實(shí)例中定義一個(gè)名為Student的枚舉類型,它可以是Name的一個(gè)相關(guān)值(Int悼凑,Int叮贩,Int)击狮,或者是Mark的一個(gè)字符串類型(String)相關(guān)值

letstuNames = Student.Name("ZhangSan")

letstuMarks = Student.Mark(98,97,95)

switchstuMarks {

case.Name(let stuName):

print("學(xué)生的名字是:\(stuName)")

case.Mark(let Mark1, let Mark2, let Mark3):

print("學(xué)生的成績(jī)是:\(Mark1),\(Mark2),\(Mark3)")

}//輸出結(jié)果:學(xué)生的成績(jī)是:

98,97,95

print(stuNames)

//原始值:原始值可以是字符串,字符益老,或者任何整型值或浮點(diǎn)型值

//在原始值為整數(shù)的枚舉時(shí)彪蓬,不需要顯式的為每一個(gè)成員賦值,Swift會(huì)自動(dòng)為你賦值捺萌。

//例如档冬,當(dāng)使用整數(shù)作為原始值時(shí),隱式賦值的值依次遞增1桃纯。如果第一個(gè)值沒(méi)有被賦初值酷誓,將會(huì)被自動(dòng)置為0

/**

enum Month: Int {

case January = 1, February, March, April, May, June, July, August, September, October, November, December

}

*/

letweekday1 = DayssofaWeek.WEDNESDAY.hashValue

print(weekday1)//輸出:3

//

//可以為結(jié)構(gòu)體定義屬性(常量、變量)和添加方法态坦,從而擴(kuò)展結(jié)構(gòu)體的功能

/**區(qū)別于C和OC:

結(jié)構(gòu)體不需要包含實(shí)現(xiàn)文件和接口盐数。

結(jié)構(gòu)體允許我們創(chuàng)建一個(gè)單一文件,且系統(tǒng)會(huì)自動(dòng)生成面向其它代碼的外部接口伞梯。

*/

//結(jié)構(gòu)體總是通過(guò)被復(fù)制的方式在代碼中傳遞玫氢,因此它的值是不可修改的

// (1)語(yǔ)法:關(guān)鍵字struct

/**

struct nameStruct {

Definition 1

Definition 2

……

Definition N

}

*/

structsturentsMarksStruct {

varEnglish:Int=100

varChines:Int=99

varmath:Int=98

}

//我們可以通過(guò)結(jié)構(gòu)體名來(lái)訪問(wèn)結(jié)構(gòu)體成員。結(jié)構(gòu)體實(shí)例化使用let關(guān)鍵字:

letmyMarks =sturentsMarksStruct()

print("我的成績(jī)是:", myMarks.English, myMarks.math, myMarks.Chines)

//以下實(shí)例化通過(guò)結(jié)構(gòu)體實(shí)例化時(shí)傳值并克隆一個(gè)結(jié)構(gòu)體

structYourMarksStruct {

varmark :Int

init(mark:Int) {

self.mark = mark

}

}

varaStruct =YourMarksStruct(mark:99)

aStruct.mark =100

varbStruct = aStruct

bStruct.mark =97

print(aStruct.mark, bStruct.mark)// 100, 97

// (2)結(jié)構(gòu)體應(yīng)用:

//結(jié)構(gòu)體實(shí)例總是通過(guò)值傳遞來(lái)定義你的自定義數(shù)據(jù)類型

/**按照通用的準(zhǔn)則谜诫,當(dāng)符合一條或多條以下條件時(shí)漾峡,請(qǐng)考慮構(gòu)建結(jié)構(gòu)體:

結(jié)構(gòu)體的主要目的是用來(lái)封裝少量相關(guān)簡(jiǎn)單數(shù)據(jù)值。

有理由預(yù)計(jì)一個(gè)結(jié)構(gòu)體實(shí)例在賦值或傳遞時(shí)喻旷,封裝的數(shù)據(jù)將會(huì)被拷貝而不是被引用生逸。

任何在結(jié)構(gòu)體中儲(chǔ)存的值類型屬性,也將會(huì)被拷貝且预,而不是被引用槽袄。

結(jié)構(gòu)體不需要去繼承另一個(gè)已存在類型的屬性或者行為。

*/

//結(jié)構(gòu)體實(shí)例是通過(guò)值傳遞而不是通過(guò)引用傳遞

//

// (1)類與結(jié)構(gòu)體對(duì)比

/**與結(jié)構(gòu)體相比锋谐,類還有如下的附加功能:

繼承允許一個(gè)類繼承另一個(gè)類的特征

類型轉(zhuǎn)換允許在運(yùn)行時(shí)檢查和解釋一個(gè)類實(shí)例的類型

解構(gòu)器允許一個(gè)類實(shí)例釋放任何其所被分配的資源

引用計(jì)數(shù)允許對(duì)一個(gè)類的多次引用

*/

/**語(yǔ)法:

Class classname {

Definition 1

Definition 2

……

Definition N

}

*/

// (2)作為引用類型訪問(wèn)類屬性:類的屬性可以通過(guò).來(lái)訪問(wèn)掰伸。格式為:實(shí)例化類名.屬性名

// (3)恒等運(yùn)算符:

//因?yàn)轭愂且妙愋停锌赡苡卸鄠€(gè)常量和變量在后臺(tái)同時(shí)引用某一個(gè)類實(shí)例怀估。

/**為了能夠判定兩個(gè)常量或者變量是否引用同一個(gè)類實(shí)例,Swift內(nèi)建了兩個(gè)恒等運(yùn)算符:

恒等運(yùn)算符不恒等運(yùn)算符

運(yùn)算符為:===運(yùn)算符為:!==

如果兩個(gè)常量或者變量引用同一個(gè)類實(shí)例則返回true如果兩個(gè)常量或者變量引用不同一個(gè)類實(shí)例則返回true

*/

//

// Swift屬性將值跟特定的類合搅、結(jié)構(gòu)或枚舉關(guān)聯(lián)多搀。屬性可分為存儲(chǔ)屬性和計(jì)算屬性

/**

存儲(chǔ)屬性計(jì)算屬性

存儲(chǔ)常量或變量作為實(shí)例的一部分計(jì)算(而不是存儲(chǔ))一個(gè)值

用于類和結(jié)構(gòu)體用于類、結(jié)構(gòu)體和枚舉

*/

// (1)存儲(chǔ)屬性:簡(jiǎn)單來(lái)說(shuō)灾部,一個(gè)存儲(chǔ)屬性就是存儲(chǔ)在特定類或結(jié)構(gòu)體的實(shí)例里的一個(gè)常量或變量康铭。

// (2)延遲存儲(chǔ)屬性:延遲存儲(chǔ)屬性是指當(dāng)?shù)谝淮伪徽{(diào)用的時(shí)候才會(huì)計(jì)算其初始值的屬性。在屬性聲明前使用lazy來(lái)標(biāo)示一個(gè)延遲存儲(chǔ)屬性赌髓。

/**

*注意:

必須將延遲存儲(chǔ)屬性聲明成變量(使用var關(guān)鍵字)从藤,因?yàn)閷傩缘闹翟趯?shí)例構(gòu)造完成之前可能無(wú)法得到催跪。而常量屬性在構(gòu)造過(guò)程完成之前必須要有初始值,因此無(wú)法聲明成延遲屬性夷野。

*/

// (3)實(shí)例化變量:一個(gè)類型中屬性的全部信息——包括命名懊蒸、類型和內(nèi)存管理特征——都在唯一一個(gè)地方(類型定義中)定義。

// (4)計(jì)算屬性:除存儲(chǔ)屬性外悯搔,類骑丸、結(jié)構(gòu)體和枚舉可以定義計(jì)算屬性,計(jì)算屬性不直接存儲(chǔ)值妒貌,而是提供一個(gè)getter來(lái)獲取值通危,一個(gè)可選的setter來(lái)間接設(shè)置其他屬性或變量的值

// (5)只讀計(jì)算屬性:只有g(shù)etter沒(méi)有setter的計(jì)算屬性就是只讀計(jì)算屬性

//必須使用var關(guān)鍵字定義計(jì)算屬性,包括只讀計(jì)算屬性灌曙,因?yàn)樗鼈兊闹挡皇枪潭ǖ木盏et關(guān)鍵字只用來(lái)聲明常量屬性,表示初始化后再也無(wú)法修改的值在刺。

// (6)屬性觀察器:屬性觀察器監(jiān)控和響應(yīng)屬性值的變化逆害,每次屬性被設(shè)置值的時(shí)候都會(huì)調(diào)用屬性觀察器,甚至新的值和現(xiàn)在的值相同的時(shí)候也不例外增炭。

// (7)全局變量和局部變量:計(jì)算屬性和屬性觀察器所描述的模式也可以用于全局變量和局部變量

/**

局部變量全局變量

在函數(shù)忍燥、方法或閉包內(nèi)部定義的變量。函數(shù)隙姿、方法梅垄、閉包或任何類型之外定義的變量。

用于存儲(chǔ)和檢索值输玷。用于存儲(chǔ)和檢索值队丝。

存儲(chǔ)屬性用于獲取和設(shè)置值。存儲(chǔ)屬性用于獲取和設(shè)置值欲鹏。

也用于計(jì)算屬性机久。也用于計(jì)算屬性。

*/

// (8)類型屬性:類型屬性是作為類型定義的一部分寫在類型最外層的花括號(hào)({})內(nèi)赔嚎。

//使用關(guān)鍵字static來(lái)定義值類型的類型屬性膘盖,關(guān)鍵字class來(lái)為類定義類型屬性。

structTeachers {

staticvarEnglish =""

staticvarcomputedTypeProperty:Int{

return3

}

}

enumTYpessss {

staticvarTypeAA =""

staticvarTypeBB:Int{

return3

}

functypeDid(a:Int) ->Int{

print(">>>>>>枚舉中定義方法:", a)

returna*2

}

}

classCLASSsss {

classvarclassAAA:Int{

return3

}

}

// (9)獲取和設(shè)置類型屬性的值:類似于實(shí)例的屬性尤误,類型屬性的訪問(wèn)也是通過(guò)點(diǎn)運(yùn)算符(.)來(lái)進(jìn)行侠畔。但是,類型屬性是通過(guò)類型本身來(lái)獲取和設(shè)置损晤,而不是通過(guò)實(shí)例

//

//

// Swift方法是與某些特定類型相關(guān)聯(lián)的函數(shù)

//在Objective-C中软棺,類是唯一能定義方法的類型。但在Swift中尤勋,你不僅能選擇是否要定義一個(gè)類/結(jié)構(gòu)體/枚舉喘落,還能靈活的在你創(chuàng)建的類型(類/結(jié)構(gòu)體/枚舉)上定義方法茵宪。

// (1)實(shí)例方法:

/**語(yǔ)法:

func <#name#>(<#parameters#>) -> <#return type#> {

<#function body#>

}

*/

print(aAddB(100, b:200))

countADD(100)

print(countA)

//方法的局部參數(shù)名稱和外部參數(shù)名稱: Swift默認(rèn)僅給方法的第一個(gè)參數(shù)名稱一個(gè)局部參數(shù)名稱;默認(rèn)同時(shí)給第二個(gè)和后續(xù)的參數(shù)名稱為全局參數(shù)名稱

//例如aAddB方法中,a為局部參數(shù)名稱瘦棋,b用于全局的聲明并通過(guò)外部程序訪問(wèn)稀火。

//是否提供外部名稱設(shè)置:我們強(qiáng)制在第一個(gè)參數(shù)添加外部名稱把這個(gè)局部名稱當(dāng)作外部名稱使用(Swift

2.0前是使用#號(hào))。

//相反兽狭,我們呢也可以使用下劃線(_)設(shè)置第二個(gè)及后續(xù)的參數(shù)不提供一個(gè)外部名稱

funcparamA(first a:Int, b:Int) {

print("\(a+b)")

}

paramA(first:10, b:10)

funcparamB(a:Int, second _b:Int) {

print("\(a-_b)")

}

paramB(10, second:5)

// (2)self屬性:類型的每一個(gè)實(shí)例都有一個(gè)隱含屬性叫做self憾股,self完全等同于該實(shí)例本身。

//你可以在一個(gè)實(shí)例的實(shí)例方法中使用這個(gè)隱含的self屬性來(lái)引用當(dāng)前實(shí)例箕慧。

self.countA =100

print(self.countA)

// (3)在實(shí)例方法中修改值類型:變異(mutating)

/**

Swift語(yǔ)言中結(jié)構(gòu)體和枚舉是值類型掂铐。一般情況下带兜,值類型的屬性不能在它的實(shí)例方法中被修改哨鸭。

但是里逆,如果你確實(shí)需要在某個(gè)具體的方法中修改結(jié)構(gòu)體或者枚舉的屬性,你可以選擇變異(mutating)這個(gè)方法伐庭,然后方法就可以從方法內(nèi)部改變它的屬性粉渠;并且它做的任何改變?cè)诜椒ńY(jié)束時(shí)還會(huì)保留在原始結(jié)構(gòu)中。

方法還可以給它隱含的self屬性賦值一個(gè)全新的實(shí)例圾另,這個(gè)新實(shí)例在方法結(jié)束后將替換原來(lái)的實(shí)例霸株。

*/

varmutaMarks = MarkStruct(English:99, Chines:99, Math:95)

print(">>>>>英語(yǔ):", mutaMarks.English)

mutaMarks.subMarks(100, math:90)

print(">>>>>英語(yǔ)......:", mutaMarks.English)

// (4)在可變方法中給self賦值:可變方法能夠賦給隱含屬性self一個(gè)全新的實(shí)例。mutating

// (5)類型方法:實(shí)例方法是被類型的某個(gè)實(shí)例調(diào)用的方法集乔,你也可以定義類型本身調(diào)用的方法

//聲明結(jié)構(gòu)體和枚舉的類型方法去件,在方法的func關(guān)鍵字之前加上關(guān)鍵字static。static

//類可能會(huì)用關(guān)鍵字class來(lái)允許子類重寫父類的實(shí)現(xiàn)方法扰路。class

//類型方法和實(shí)例方法一樣用點(diǎn)號(hào)(.)語(yǔ)法調(diào)用

letminmarkss = MarkStruct.minMarks(90, math:80)

print(minmarkss)

//

// class關(guān)鍵字除了有自定義類的作用,還有聲明類方法的作用

// (1)在方法的func關(guān)鍵字之前加上關(guān)鍵字static或者class都可以用于指定類方法.

// (2)不同的是用class關(guān)鍵字指定的類方法可以被子類重寫,但是用static關(guān)鍵字指定的類方法是不能被子類重寫的

// (3)類方法和實(shí)例方法可以重名

//

/**

下標(biāo)腳本可以定義在類(Class)尤溜、結(jié)構(gòu)體(structure)和枚舉(enumeration)這些目標(biāo)中,可以認(rèn)為是訪問(wèn)對(duì)象汗唱、集合或序列的快捷方式宫莱,不需要再調(diào)用實(shí)例的特定的賦值和訪問(wèn)方法。

舉例來(lái)說(shuō)哩罪,用下標(biāo)腳本訪問(wèn)一個(gè)數(shù)組(Array)實(shí)例中的元素可以這樣寫someArray[index]授霸,訪問(wèn)字典(Dictionary)實(shí)例中的元素可以這樣寫someDictionary[key]。

對(duì)于同一個(gè)目標(biāo)可以定義多個(gè)下標(biāo)腳本际插,通過(guò)索引值類型的不同來(lái)進(jìn)行重載碘耳,而且索引值的個(gè)數(shù)可以是多個(gè)

*/

// (1)下標(biāo)腳本語(yǔ)法及應(yīng)用:

/**語(yǔ)法:

subscript(index: Int) -> Int {

get {

//用于下標(biāo)腳本值的聲明

}

set(newValue) {

//執(zhí)行賦值操作

}

}

*/

letsubscriMark = MarkStruct(English:100, Chines:100, Math:100)

print("100/10 = ", subscriMark[10])

print("100/20 = ", subscriMark[20])

letp = ViewController2()

print(p[0],"\n")

//用法:通常下標(biāo)腳本是用來(lái)訪問(wèn)集合(collection),列表(list)或序列(sequence)中元素的快捷方式腹鹉。

//你可以在你自己特定的類或結(jié)構(gòu)體中自由的實(shí)現(xiàn)下標(biāo)腳本來(lái)提供合適的功能

// (2)下標(biāo)腳本選項(xiàng):

/**

下標(biāo)腳本允許任意數(shù)量的入?yún)⑺饕⑶颐總€(gè)入?yún)㈩愋鸵矝](méi)有限制敷硅。

下標(biāo)腳本的返回值也可以是任何類型功咒。

下標(biāo)腳本可以使用變量參數(shù)和可變參數(shù)愉阎。

一個(gè)類或結(jié)構(gòu)體可以根據(jù)自身需要提供多個(gè)下標(biāo)腳本實(shí)現(xiàn),在定義下標(biāo)腳本時(shí)通過(guò)傳入?yún)?shù)的類型進(jìn)行區(qū)分力奋,使用下標(biāo)腳本時(shí)會(huì)自動(dòng)匹配合適的下標(biāo)腳本實(shí)現(xiàn)運(yùn)行榜旦,這就是下標(biāo)腳本的重載。

*/

print("下標(biāo)腳本重載:10*2+2 = ",subscriMark[10,2])

//

//子類景殷,超類(或父類)

//在Swift中溅呢,類可以調(diào)用和訪問(wèn)超類的方法,屬性和下標(biāo)腳本猿挚,并且可以重寫它們咐旧。

// (1)基類:沒(méi)有繼承其它類的類,稱之為基類(Base

Class)

// (2)子類:子類指的是在一個(gè)已有類的基礎(chǔ)上創(chuàng)建一個(gè)新的類

// (3)重寫: Overriding,子類可以通過(guò)繼承來(lái)的實(shí)例方法绩蜻,類方法铣墨,實(shí)例屬性,或下標(biāo)腳本來(lái)實(shí)現(xiàn)自己的定制功能办绝,我們把這種行為叫重寫

/**

重寫訪問(wèn)方法伊约,屬性,下標(biāo)腳本

方法super.somemethod()

屬性super.someProperty()

下標(biāo)腳本super[someIndex]

*/

// (4)重寫方法和屬性:

//重寫方法:

letsuperStudent = StudentDetails()

superStudent.recordMarks()

letsubTom = Tom()

subTom.recordMarks()

//重寫屬性:你可以提供定制的getter(或setter)來(lái)重寫任意繼承來(lái)的屬性孕蝉,無(wú)論繼承來(lái)的屬性是存儲(chǔ)型的還是計(jì)算型的屬性

/**注意

如果你在重寫屬性中提供了setter屡律,那么你也一定要提供getter。

如果你不想在重寫版本中的getter里修改繼承來(lái)的屬性值降淮,你可以直接通過(guò)super.someProperty來(lái)返回繼承來(lái)的值超埋,其中someProperty是你要重寫的屬性的名字。

*/

subTom.English =100

//subTom.Math = 120 // get-only

print("重寫屬性:tom? ", subTom.Math)

// (5)重寫屬性觀察器:你可以在屬性重寫中為一個(gè)繼承來(lái)的屬性添加屬性觀察器骤肛。這樣一來(lái)纳本,當(dāng)繼承來(lái)的屬性值發(fā)生改變時(shí),你就會(huì)監(jiān)測(cè)到腋颠。

//注意:你不可以為繼承來(lái)的常量存儲(chǔ)型屬性或繼承來(lái)的只讀計(jì)算型屬性添加屬性觀察器繁成。

subTom.English =200

print(">>>>重寫:", subTom.Chines, subTom.Math)

// (6)防止重寫: final,我們可以使用final關(guān)鍵字防止它們被重寫

//如果你重寫了final方法,屬性或下標(biāo)腳本淑玫,在編譯時(shí)會(huì)報(bào)錯(cuò)巾腕。

//你可以通過(guò)在關(guān)鍵字class前添加final特性(final

class)來(lái)將整個(gè)類標(biāo)記為final的,這樣的類是不可被繼承的絮蒿,否則會(huì)報(bào)編譯錯(cuò)誤尊搬。

//構(gòu)造過(guò)程是為了使用某個(gè)類、結(jié)構(gòu)體或枚舉類型的實(shí)例而進(jìn)行的準(zhǔn)備過(guò)程土涝。這個(gè)過(guò)程包含了為實(shí)例中的每個(gè)屬性設(shè)置初始值和為其執(zhí)行必要的準(zhǔn)備和初始化任務(wù)

//構(gòu)造函數(shù): init()? ,與Object-C中的構(gòu)造器不同佛寿,swift的構(gòu)造函數(shù)無(wú)需返回值,它們的主要任務(wù)是保證新實(shí)例在第一次使用前完成正確的初始化

//類實(shí)例也可以通過(guò)定義析構(gòu)器(deinitializer)在類實(shí)例釋放之前執(zhí)行清理內(nèi)存的工作。

// (1)存儲(chǔ)型屬性的初始賦值:在實(shí)例創(chuàng)建時(shí)冀泻,必須為所有存儲(chǔ)型屬性設(shè)置合適的初始值常侣。

//存儲(chǔ)屬性在構(gòu)造器中賦值時(shí),它們的值是被直接設(shè)置的弹渔,不會(huì)觸發(fā)任何屬性觀測(cè)器胳施。

/**存儲(chǔ)屬性在構(gòu)造器中賦值流程:

創(chuàng)建初始值。

在屬性定義中指定默認(rèn)屬性值肢专。

初始化實(shí)例舞肆,并調(diào)用init()方法。

*/

// (2)構(gòu)造器: init構(gòu)造器在創(chuàng)建某特定類型的新實(shí)例時(shí)調(diào)用博杖。它的最簡(jiǎn)形式類似于一個(gè)不帶任何參數(shù)的實(shí)例方法椿胯,以關(guān)鍵字init命名。

/**語(yǔ)法:

init() {

//實(shí)例化后執(zhí)行的代碼

}

*/

//實(shí)例:以下結(jié)構(gòu)體定義了一個(gè)不帶參數(shù)的構(gòu)造器init欧募,并在里面將存儲(chǔ)型屬性length和breadth的值初始化為6和12:

structAinitaStruct {

varlength:Double

varwidth:Double

varr =3.5// (3)默認(rèn)屬性值

init() {

length =5.5

width =9

}

}

letareaA =AinitaStruct()

print("矩形的面積:\(areaA.length * areaA.width)")

// (3)默認(rèn)屬性值:我們可以在構(gòu)造器中為存儲(chǔ)型屬性設(shè)置初始值压状;同樣,也可以在屬性聲明時(shí)為其設(shè)置默認(rèn)值跟继。

//使用默認(rèn)值能讓你的構(gòu)造器更簡(jiǎn)潔种冬、更清晰,且能通過(guò)默認(rèn)值自動(dòng)推導(dǎo)出屬性的類型舔糖。

// (4)構(gòu)造參數(shù):你可以在定義構(gòu)造器init()時(shí)提供構(gòu)造參數(shù)娱两,如下所示:

structAparamStruct {

varlength :Double

varwidth :Double

vararea :Double

init(fromLength length:Double, fromWidth width:Double) {

self.length = length

self.width = width

area = length * width

}

init(fromLg lg:Double, fromWd wd:Double) {

self.length = lg

self.width = wd

area = lg * wd

}

}

letareaPA =AparamStruct(fromLength:10, fromWidth:20)

letareaPB =AparamStruct(fromLg:100, fromWd:200)

letareaPC =AparamStruct.init(fromLength:5,

fromWidth:10)

print("areaPA:\(areaPA.area), ? areaPB:\(areaPB.area),

areaPC:\(areaPC)")

// (5)內(nèi)部和外部參數(shù)名:如果你在定義構(gòu)造器時(shí)沒(méi)有提供參數(shù)的外部名字,Swift會(huì)為每個(gè)構(gòu)造器的參數(shù)自動(dòng)生成一個(gè)跟內(nèi)部名字相同的外部名金吗。

structColor {

letred, green, blue:Double

init(red:Double, green:Double, blue:Double)

{

self.red = red

self.green = green

self.blue = blue

}

init(white:Double) {

red = white

green = white

blue = white

}

}

letpurpleColor =Color.init(red:255,

green:222, blue:111)

letyellowColor =Color.init(white:200)

print(purpleColor.red, yellowColor.red)

//沒(méi)有外部參數(shù)名稱:如果你不希望為構(gòu)造器的某個(gè)參數(shù)提供外部名字十兢,你可以使用下劃線_來(lái)顯示描述它的外部名

structColorNO {

letred:Double

init(_white:Double) {

red = white

}

}

letnoColorA =ColorNO.init(100)

print(">>>>>>>>沒(méi)有外物參數(shù):noColorA = ", noColorA.red)

// (6)可選屬性類型:如果你定制的類型包含一個(gè)邏輯上允許取值為空的存儲(chǔ)型屬性,你都需要將它定義為可選類型optional

type(可選屬性類型)摇庙。

//當(dāng)存儲(chǔ)屬性聲明為可選時(shí)旱物,將自動(dòng)初始化為空nil

structRGB {

varred :Double?

letgreen :Double?// (7)green屬性現(xiàn)在是常量

init(white:Double) {

red = white +10

green = red! +10// (7)仍然可以在構(gòu)造器中設(shè)置值

}

init(_black:Double) {

red = black

green = red! +100

}

}

letRGBa =RGB.init(white:100)

letRGBb =RGB.init(200)

// print(RGBa.red, RGBb.red) //輸出結(jié)果Optional(110.0) Optional(200.0)

print(RGBa.red!, RGBb.red!)//輸出結(jié)果110.0 200.0

// (7)構(gòu)造過(guò)程中修改常量屬性:只要在構(gòu)造過(guò)程結(jié)束前常量的值能確定,你可以在構(gòu)造過(guò)程中的任意時(shí)間點(diǎn)修改常量屬性的值

//對(duì)某個(gè)類實(shí)例來(lái)說(shuō)卫袒,它的常量屬性只能在定義它的類的構(gòu)造過(guò)程中修改宵呛;不能在子類中修改

// (8)默認(rèn)構(gòu)造器:默認(rèn)構(gòu)造器將簡(jiǎn)單的創(chuàng)建一個(gè)所有屬性值都設(shè)置為默認(rèn)值的實(shí)例

//以下實(shí)例中,ShoppingListItem類中的所有屬性都有默認(rèn)值夕凝,且它是沒(méi)有父類的基類宝穗,它將自動(dòng)獲得一個(gè)可以為所有屬性設(shè)置默認(rèn)值的默認(rèn)構(gòu)造器

letitem = ShoppingListItem()

print("默認(rèn)構(gòu)造器:", item.name, item.quantity, item.purchased)//輸出結(jié)果:默認(rèn)構(gòu)造器:nil 1 false

//結(jié)構(gòu)體的逐一成員構(gòu)造器:如果結(jié)構(gòu)體對(duì)所有存儲(chǔ)型屬性提供了默認(rèn)值且自身沒(méi)有提供定制的構(gòu)造器,它們能自動(dòng)獲得一個(gè)逐一成員構(gòu)造器码秉。

//我們?cè)谡{(diào)用逐一成員構(gòu)造器時(shí)逮矛,通過(guò)與成員屬性名相同的參數(shù)名進(jìn)行傳值來(lái)完成對(duì)成員屬性的初始賦值。

structShopping {

varlength =100.0

varwidth =200.0

}

letshopA =Shopping.init(length:33.0,

width:24.0)

print("結(jié)構(gòu)體的逐一成員變量:", shopA.length*shopA.width)

// (9)值類型的構(gòu)造器代理:構(gòu)造器可以通過(guò)調(diào)用其它構(gòu)造器來(lái)完成實(shí)例的部分構(gòu)造過(guò)程转砖。這一過(guò)程稱為構(gòu)造器代理须鼎,它能減少多個(gè)構(gòu)造器間的代碼重復(fù)。

//以下實(shí)例中,RectA結(jié)構(gòu)體調(diào)用了SizeA和PointA的構(gòu)造過(guò)程:

structSizeA {

varwidth =0.0, height =0.0

}

structPointA {

varx =0.0, y =0.0

}

structRectA {

varorigin = PointA()// origin屬性使用定義時(shí)的默認(rèn)值PointA(x:

0.0, y: 0.0)

varsize = SizeA()

init() {}

init(origin:PointA, size:SizeA) {

self.origin = origin

self.size = size

}

init(center:PointA, size:SizeA) {

//先通過(guò)center和size的值計(jì)算出origin的坐標(biāo)

letoriginX = center.x - size.width/2

letoriginY = center.y? - size.height/2

//然后再調(diào)用(或代理給)init(origin:size:)構(gòu)造器來(lái)將新的origin和size值賦值到對(duì)應(yīng)的屬性中

self.init(origin: PointA.init(x: originX, y: originY),

size: size)

}

}

letrectA =RectA()

print("PointA結(jié)構(gòu)體初始值:\(rectA.origin.x,

rectA.origin.y)")//輸出結(jié)果:PointA結(jié)構(gòu)體初始值:(0.0, 0.0)

//將origin和size的參數(shù)值賦給對(duì)應(yīng)的存儲(chǔ)型屬性

letrectB =RectA.init(origin: PointA(x:56.0,

y:45.0), size:SizeA(width:100.0, height:200.0))

print("PointB結(jié)構(gòu)體初始值:\(rectB.origin.x,

rectB.origin.y)")//輸出結(jié)果:PointB結(jié)構(gòu)體初始值:(56.0, 45.0)

//先通過(guò)center和size的值計(jì)算出origin的坐標(biāo)晋控。

//然后再調(diào)用(或代理給)init(origin:size:)構(gòu)造器來(lái)將新的origin和size值賦值到對(duì)應(yīng)的屬性中

letrectC =RectA.init(center: PointA(x:10.0,

y:10.0), size:SizeA(width:24.0, height:25.0))

print("PointC結(jié)構(gòu)體初始值:\(rectC.origin.x,

rectC.origin.y)")//輸出結(jié)果:PointC結(jié)構(gòu)體初始值:(-2.0, -2.5)

/**構(gòu)造器代理規(guī)則:

值類型:不支持繼承挑围,所以構(gòu)造器代理的過(guò)程相對(duì)簡(jiǎn)單,因?yàn)樗鼈冎荒艽斫o本身提供的其它構(gòu)造器糖荒。可以使用self.init在自定義的構(gòu)造器中引用其它的屬于相同值類型的構(gòu)造器模捂。

類類型:它可以繼承自其它類,這意味著類有責(zé)任保證其所有繼承的存儲(chǔ)型屬性在構(gòu)造時(shí)也能正確的初始化捶朵。

*/

// (10)類的繼承和構(gòu)造過(guò)程: Swift提供了兩種類型的類構(gòu)造器來(lái)確保所有類實(shí)例中存儲(chǔ)型屬性都能獲得初始值,它們分別是指定構(gòu)造器和便利構(gòu)造器狂男。

/**

指定構(gòu)造器:類中最主要的構(gòu)造器

初始化類中提供的所有屬性综看,并根據(jù)父類鏈往上調(diào)用父類的構(gòu)造器來(lái)實(shí)現(xiàn)父類的初始化。

每一個(gè)類都必須擁有至少一個(gè)指定構(gòu)造器

Init(parameters) {

statements

}

便利構(gòu)造器:類中比較次要的岖食、輔助型的構(gòu)造器

可以定義便利構(gòu)造器來(lái)調(diào)用同一個(gè)類中的指定構(gòu)造器红碑,并為其參數(shù)提供默認(rèn)值。你也可以定義便利構(gòu)造器來(lái)創(chuàng)建一個(gè)特殊用途或特定輸入的實(shí)例泡垃。

只在必要的時(shí)候?yàn)轭愄峁┍憷麡?gòu)造器

convenience init(parameters) {

statements

}

*/

letyuebing = Mooncake.init(huaMei:"華美月餅")

letyuebing1 = Ronglang.init(huaMei:"華美月餅",

rongLang:"榮朗月餅")

print(">>>>華美:\(yuebing.huamei),

\n, >>>>>華美:\(yuebing1.huamei),

\n, >>>>>榮朗:\(yuebing1.ronglang)")

letcar = carCalss(aoDI:"奧迪析珊。。蔑穴。")

// let aodi = AODIClass(aoDI: "奧迪忠寻、、存和、", daZhong: "大眾奕剃、、捐腿、")

letaodi = AODIClass.init(aoDI:"奧迪")

print("car:\(car.aodi) \n AODI:\(aodi.aodi,

aodi.dazhong)")

// (11)構(gòu)造器的繼承和重載: Swift中的子類不會(huì)默認(rèn)繼承父類的構(gòu)造器

//父類的構(gòu)造器僅在確定和安全的情況下被繼承纵朋。當(dāng)你重寫一個(gè)父類指定構(gòu)造器時(shí),你需要寫override修飾符茄袖。

letwine = WineClass()

print(wine.desccription)//輸出結(jié)果:紅酒不錯(cuò)操软!

letredwine = REDWineClass()

print(redwine.desccription)//輸出結(jié)果:紅酒名酒。绞佩。寺鸥。不錯(cuò)!

//指定構(gòu)造器和便利構(gòu)造器實(shí)例:接下來(lái)的例子將在操作中展示指定構(gòu)造器品山、便利構(gòu)造器和自動(dòng)構(gòu)造器的繼承胆建。

//它定義了包含兩個(gè)個(gè)類MainClass、SubClass的類層次結(jié)構(gòu)肘交,并將演示它們的構(gòu)造器是如何相互作用的笆载。

letgame = GameClass(mobilegame:"精靈寶")

print("game :\(game.mobileGames)")//輸出結(jié)果:game :精靈寶

letgame1 = GameClass()

print("game none :\(game1.mobileGames)")//輸出結(jié)果:

game none :逐鹿天下手游

letmobile = MobileGameClass.init(mobilegame:"紀(jì)念碑谷")

print("mobile one :\(mobile.mobileGames)")//輸出結(jié)果:

mobile one :紀(jì)念碑谷

letmobile1 = MobileGameClass.init(moblegame:"夢(mèng)幻西游",

zhulu:"酷跑")

print("mobile1 two :\(mobile1.zhuluGame)")//輸出結(jié)果:

mobile1 two :酷跑

// (12)類的可失敗構(gòu)造器:如果一個(gè)類,結(jié)構(gòu)體或枚舉類型的對(duì)象,在構(gòu)造自身的過(guò)程中有可能失敗凉驻,則為其定義一個(gè)可失敗構(gòu)造器腻要。

//其語(yǔ)法為在init關(guān)鍵字后面加添問(wèn)號(hào)(init?)

/**變量初始化失敗可能的原因有:

傳入無(wú)效的參數(shù)值。

缺少某種所需的外部資源涝登。

沒(méi)有滿足特定條件雄家。

*/

structGameStruct {

letgame:String

init?(zhulu:String) {

ifzhulu.isEmpty {

returnnil

}else{

self.game = zhulu

}

}

}

//通過(guò)該可失敗構(gòu)造器來(lái)構(gòu)建一個(gè)GameStruct的對(duì)象,并檢查其構(gòu)建過(guò)程是否成功

// gameZhulu的類型是GameStruct?而不是GameStruct

letgameZhulu =GameStruct.init(zhulu:"逐鹿天下胀滚,》》》")

ifletzhulu = gameZhulu {

print("可失敗構(gòu)造器:\(zhulu.game)")

}

//枚舉類型的可失敗構(gòu)造器

// (13)覆蓋一個(gè)可失敗構(gòu)造器

//就如同其它構(gòu)造器一樣趟济,你也可以用子類的可失敗構(gòu)造器覆蓋基類的可失敗構(gòu)造器。

//者你也可以用子類的非可失敗構(gòu)造器覆蓋一個(gè)基類的可失敗構(gòu)造器咽笼。

//你可以用一個(gè)非可失敗構(gòu)造器覆蓋一個(gè)可失敗構(gòu)造器顷编,但反過(guò)來(lái)卻行不通。

//一個(gè)非可失敗的構(gòu)造器永遠(yuǎn)也不能代理調(diào)用一個(gè)可失敗構(gòu)造器剑刑。

letplName = planet(name:"Mercury")

print("行星的名字是:\(plName.name)")//行星的名字是:

Mercury

letnopName = planet()

print("沒(méi)有這個(gè)星星的名字:\(nopName.name)")//沒(méi)有這個(gè)名字的行星:

[No Planets]

// (14)可失敗構(gòu)造器init!

//通常來(lái)說(shuō)我們通過(guò)在init關(guān)鍵字后添加問(wèn)號(hào)的方式(init?)來(lái)定義一個(gè)可失敗構(gòu)造器媳纬,但你也可以使用通過(guò)在init后面添加驚嘆號(hào)的方式來(lái)定義一個(gè)可失敗構(gòu)造器(init!)

letstmaek = StuRecord(stname:"Runoob")

ifletname = stmaek {

print("指定了學(xué)生名:\(name)")//指定了學(xué)生名:

}

letblankname = StuRecord(stname:"")

ifblankname ==nil{

print("學(xué)生名為空")//學(xué)生名為空

}

//

// deinit :在一個(gè)類的實(shí)例被釋放之前,析構(gòu)函數(shù)被立即調(diào)用施掏。用關(guān)鍵字deinit來(lái)標(biāo)示析構(gòu)函數(shù)钮惠,類似于初始化函數(shù)用init來(lái)標(biāo)示。析構(gòu)函數(shù)只適用于類類型七芭。

/**析構(gòu)過(guò)程原理:

Swift會(huì)自動(dòng)釋放不再需要的實(shí)例以釋放資源萌腿。

Swift通過(guò)自動(dòng)引用計(jì)數(shù)(ARC)處理實(shí)例的內(nèi)存管理。

通常當(dāng)你的實(shí)例被釋放時(shí)不需要手動(dòng)地去清理抖苦。但是毁菱,當(dāng)使用自己的資源時(shí),你可能需要進(jìn)行一些額外的清理锌历。

例如贮庞,如果創(chuàng)建了一個(gè)自定義的類來(lái)打開(kāi)一個(gè)文件,并寫入一些數(shù)據(jù)究西,你可能需要在類實(shí)例被釋放之前關(guān)閉該文件窗慎。

*/

/**語(yǔ)法:在類的定義中,每個(gè)類最多只能有一個(gè)析構(gòu)函數(shù)卤材。析構(gòu)函數(shù)不帶任何參數(shù)遮斥,在寫法上不帶括號(hào):

deinit {

//執(zhí)行析構(gòu)過(guò)程

}

*/

varshow:BaseClass? = BaseClass()

varhide:BaseClass? = BaseClass.init()

print("有值:", counter)//輸出:有值:2

show =nil//當(dāng)show = nil語(yǔ)句執(zhí)行后,計(jì)算器減1扇丛,show占用的內(nèi)存就會(huì)釋放术吗。

hide =nil

print("置空:", counter)//輸出:置空:0

print(show, hide)//輸出:nil nil

//

// ARC這一機(jī)制跟蹤和管理應(yīng)用程序的內(nèi)存。通常不需要手動(dòng)釋放內(nèi)存帆精,因?yàn)锳RC會(huì)在類的實(shí)例不再被使用時(shí)较屿,自動(dòng)釋放其占用的內(nèi)存

/** ARC功能:

init() ,當(dāng)每次使用init()方法創(chuàng)建一個(gè)類的新的實(shí)例的時(shí)候隧魄,ARC會(huì)分配一大塊內(nèi)存用來(lái)儲(chǔ)存實(shí)例的信息。

內(nèi)存中包含實(shí)例的類型信息隘蝎,以及這個(gè)實(shí)例所有相關(guān)屬性的值

當(dāng)實(shí)例不再被使用時(shí)购啄,ARC釋放實(shí)例所占用的內(nèi)存,并讓釋放的內(nèi)存能挪作他用嘱么。

為了確保使用中的實(shí)例不會(huì)被銷毀狮含,ARC會(huì)跟蹤和計(jì)算每一個(gè)實(shí)例正在被多少屬性,常量和變量所引用曼振。

實(shí)例賦值給屬性辉川、常量或變量,它們都會(huì)創(chuàng)建此實(shí)例的強(qiáng)引用拴测,只要強(qiáng)引用還在,實(shí)例是不允許被銷毀的府蛇。

*/

//值會(huì)被自動(dòng)初始化為nil,目前還不會(huì)引用到BaseClass類的實(shí)例

varbaseC :BaseClass?

varbaseC1 :BaseClass?

varbaseC2 :BaseClass?

//創(chuàng)建BaseClass類的實(shí)例

baseC = BaseClass()

//賦值給其他兩個(gè)變量集索,該實(shí)例又會(huì)多出兩個(gè)強(qiáng)引用

baseC1 = baseC

baseC2 = baseC

//斷開(kāi)第一個(gè)強(qiáng)引用

baseC =nil

//斷開(kāi)第二個(gè)強(qiáng)引用

baseC1 =nil

//斷開(kāi)第三個(gè)強(qiáng)引用,并調(diào)用析構(gòu)函數(shù)

baseC2 =nil

print(baseC1, baseC2)

//在上面的例子中汇跨,ARC會(huì)跟蹤你所新創(chuàng)建的BaseClass實(shí)例的引用數(shù)量务荆,并且會(huì)在BaseClass實(shí)例不再被需要時(shí)銷毀它

// ***類實(shí)例之間的循環(huán)強(qiáng)引用

// ***類實(shí)例之間的循環(huán)強(qiáng)引用

//一個(gè)類永遠(yuǎn)不會(huì)有0個(gè)強(qiáng)引用,這種情況發(fā)生在兩個(gè)類實(shí)例相互保持對(duì)方的強(qiáng)引用穷遂,并讓對(duì)方不被銷毀函匕,這就是所謂的循環(huán)強(qiáng)引用

//兩個(gè)變量都被初始化為nil

varbasesingcalss :SignClass?

varbasessclass :SSClass?

//賦值

basesingcalss = SignClass.init(name:"BaseSignClass")

basessclass = SSClass.init(number:73)

//意感嘆號(hào)是用來(lái)展開(kāi)和訪問(wèn)可選變量runoob和number73中的實(shí)例

//循環(huán)強(qiáng)引用被創(chuàng)建

basesingcalss!.baseSs = basessclass

basessclass!.baseSign = basesingcalss

//斷開(kāi)basesingcalss和basessclass變量所持有的強(qiáng)引用時(shí),引用計(jì)數(shù)并不會(huì)降為0蚪黑,實(shí)例也不會(huì)被ARC銷毀

//注意盅惜,當(dāng)你把這兩個(gè)變量設(shè)置為nil時(shí),沒(méi)有任何一個(gè)析構(gòu)函數(shù)被調(diào)用

//強(qiáng)引用循環(huán)阻止了SignClass忌穿,SSClass類實(shí)例的銷毀抒寂,并在你的應(yīng)用程序中造成了內(nèi)存泄露

basesingcalss =nil

basessclass =nil

print("循環(huán)請(qǐng)引用", basesingcalss, basessclass)

//解決實(shí)例之間的循環(huán)強(qiáng)引用:weak弱引用,unowned無(wú)主引用

//此兩種引用允許循環(huán)引用中的一個(gè)實(shí)例引用另外一個(gè)實(shí)例而不保持強(qiáng)引用掠剑,這樣實(shí)例能夠相互引用而不產(chǎn)生循環(huán)強(qiáng)引用

//對(duì)于生命周期中會(huì)變?yōu)閚il的實(shí)例使用弱引用屈芜,相反的,對(duì)于初始化賦值后再也不會(huì)被賦值為nil的實(shí)例朴译,使用無(wú)主引用井佑。

//弱引用實(shí)例

vartoc :Module?

varlist :SubModul?

toc = Module.init(name:"ARC")

list = SubModul.init(number:4)

toc!.sub = list

list!.topic = toc

toc =nil

list =nil

print("弱引用", basesingcalss, basessclass)

//無(wú)主引用實(shí)例

varpeter :StudentPeter?

peter = StudentPeter.init(name:"Peter")

peter!.section = MarkPeter.init(marks:99, stname: peter!)

peter =nil

// ***閉包引起的循環(huán)強(qiáng)引用

// ***閉包引起的循環(huán)強(qiáng)引用

//當(dāng)你將一個(gè)閉包賦值給類實(shí)例的某個(gè)屬性,并且這個(gè)閉包體中又使用了實(shí)例眠寿。這個(gè)閉包體中可能訪問(wèn)了實(shí)例的某個(gè)屬性躬翁,例如self.someProperty,或者閉包中調(diào)用了實(shí)例的某個(gè)方法盯拱,例如self.someMethod姆另。這兩種情況導(dǎo)致了閉包“捕獲”self喇肋,從而產(chǎn)生了循環(huán)引用。

//創(chuàng)建實(shí)例并打印信息

varparagraph:HTMLElement?

paragraph = HTMLElement.init(name:"pp", text:"hellow, world")

//? ? ? ? print(paragraph!.asHTML)

//解決閉包引起的循環(huán)強(qiáng)引用:在定義閉包時(shí)同時(shí)定義捕獲列表作為閉包的一部分迹辐,通過(guò)這種方式可以解決閉包和類實(shí)例之間的循環(huán)強(qiáng)引用

/**弱引用和無(wú)主引用

當(dāng)閉包和捕獲的實(shí)例總是互相引用時(shí)并且總是同時(shí)銷毀時(shí)蝶防,將閉包內(nèi)的捕獲定義為無(wú)主引用。

相反的明吩,當(dāng)捕獲引用有時(shí)可能會(huì)是nil時(shí)间学,將閉包內(nèi)的捕獲定義為弱引用。

如果捕獲的引用絕對(duì)不會(huì)置為nil印荔,應(yīng)該用無(wú)主引用低葫,而不是弱引用。

*/

print(paragraph!.asasHTML())

// HTMLElement實(shí)例將會(huì)被銷毀仍律,并能看到它的析構(gòu)函數(shù)打印出的消息

paragraph =nil

//

/**檢測(cè)is嘿悬,轉(zhuǎn)換as

Swift語(yǔ)言類型轉(zhuǎn)換可以判斷實(shí)例的類型。也可以用于檢測(cè)實(shí)例類型是否屬于其父類或者子類的實(shí)例水泉。

Swift中類型轉(zhuǎn)換使用is和as操作符實(shí)現(xiàn)感帅,is用于檢測(cè)值的類型汗菜,as用于轉(zhuǎn)換類型腊满。

類型轉(zhuǎn)換也可以用來(lái)檢查一個(gè)類是否實(shí)現(xiàn)了某個(gè)協(xié)議雄妥。

*/

// (1)定義一個(gè)類層次

//類型轉(zhuǎn)換用于檢測(cè)實(shí)例類型是否屬于特定的實(shí)例類型

//你可以將它用在類和子類的層次結(jié)構(gòu)上,檢查特定類實(shí)例的類型并且轉(zhuǎn)換這個(gè)類實(shí)例的類型成為這個(gè)層次結(jié)構(gòu)中的其他類型炕横。

classSubjects {

varphysics :String

init(physics :String) {

self.physics = physics

}

}

classChemistry :Subjects{

varequations :String

init(physics:String, equations:String) {

self.equations = equations

super.init(physics: physics)

}

}

classMaths:Subjects{

varformulae :String

init(physics :String, formulae :String) {

self.formulae = formulae

super.init(physics: physics)

}

}

letsa = [Chemistry(physics:"固體物理",

equations:"赫茲"),

Maths(physics:"流體動(dòng)力學(xué)",

formulae:"千兆赫"),

Maths(physics:"流體動(dòng)力學(xué)",

formulae:"千兆赫"),]

letsamplechem =Chemistry.init(physics:"固體物理",

equations:"赫茲")

print("實(shí)例物理學(xué)史:\(samplechem.physics)")

print("實(shí)例方程式:\(samplechem.equations)\(sa[0].physics)")

letsamplemaths =Maths(physics:"流體動(dòng)力學(xué)",

formulae:"千兆赫")

print("實(shí)例物理學(xué)是:\(samplemaths.physics)")

print("實(shí)例公式是:\(samplemaths.formulae)")

//(2)檢查類型:關(guān)鍵字is

//操作符is來(lái)檢查一個(gè)實(shí)例是否屬于特定子類型源内。若實(shí)例屬于那個(gè)子類型,類型檢查操作符返回true份殿,否則返回false膜钓。

varchemCount =0

varmathsCount =0

foriteminsa {

ifitemisChemistry{

chemCount +=1

}else{

mathsCount +=1

}

}

print("化學(xué)科目包含:\(chemCount)個(gè),數(shù)學(xué)包含:\(mathsCount)個(gè)主題")//化學(xué)科目包含:1個(gè)卿嘲,數(shù)學(xué)包含:2個(gè)主題

// (3)向下轉(zhuǎn)型: as?或as!

// as?當(dāng)你不確定向下轉(zhuǎn)型可以成功時(shí)呻此,用類型轉(zhuǎn)換的條件形式(as?)。條件形式的類型轉(zhuǎn)換總是返回一個(gè)可選值(optional

value)腔寡,并且若下轉(zhuǎn)是不可能的焚鲜,可選值將是nil。

// as!只有你可以確定向下轉(zhuǎn)型一定會(huì)成功時(shí)放前,才使用強(qiáng)制形式(as!)忿磅。當(dāng)你試圖向下轉(zhuǎn)型為一個(gè)不正確的類型時(shí),強(qiáng)制形式的類型轉(zhuǎn)換會(huì)觸發(fā)一個(gè)運(yùn)行時(shí)錯(cuò)誤凭语。

foriteminsa {

//類型轉(zhuǎn)換的條件形式

ifletshow = itemas?Chemistry{

print("化學(xué)主題是: '\(show.physics)',\(show.equations)")

//強(qiáng)制形式

}elseifletexample = itemas?Maths{

print("數(shù)學(xué)主題是: '\(example.physics)',\(example.formulae)")

}

}

// (4)Any和AnyObject的類型轉(zhuǎn)換

// AnyObject :可以代表任何class類型的實(shí)例,? Any可以代表任何類型葱她,包括方法類(function types)

//注意:只有當(dāng)你明確的需要它的行為和功能時(shí)才使用Any和AnyObject。在你的代碼里使用你期望的明確的類型總是更好的

// Any實(shí)例:

//可以存儲(chǔ)Any類型的數(shù)組exampleany

varexampleany = [Any]()

exampleany.append(12)

exampleany.append(3.14159)

exampleany.append("Any實(shí)例")

exampleany.append(Chemistry(physics:"固體物理",

equations:"赫茲"))

foriteminexampleany {

switchitem {

caseletsomeIntasInt:

print("整型值為\(someInt)")

caseletsomeDoubleasDouble:

print("Pi值為\(someDouble)")

caseletsomeStringasString:

print("\(someString)")

caseletphyasChemistry:

print("主題'\(phy.physics)',\(phy.equations)")

default:

print("None")

}

}

// AnyObject實(shí)例

letsaprint : [AnyObject] = [Chemistry.init(physics:"11",

equations:"aa"),

Maths.init(physics:"22", formulae:"bb"),

Chemistry.init(physics:"33", equations:"cc"),

Maths.init(physics:"44", formulae:"dd")]

foriteminsaprint {

//類型轉(zhuǎn)換的條件形式

ifletshow = itemas?Chemistry{

print("化學(xué)主題是: '\(show.physics)',\(show.equations)")

//強(qiáng)制形式

}elseifletexample = itemas?Maths{

print("數(shù)學(xué)主題是: '\(example.physics)',\(example.formulae)")

}

}

//

//擴(kuò)展就是向一個(gè)已有的類似扔、結(jié)構(gòu)體或枚舉類型添加新的功能

//擴(kuò)展可以對(duì)一個(gè)已有的類型添加新的功能吨些,但是不能重寫已有的功能

/** swift中的擴(kuò)展可以:

添加計(jì)算型屬性和計(jì)算型靜態(tài)屬性

定義實(shí)例方法和類型方法

提供新的構(gòu)造器

定義下標(biāo)

定義和使用新的嵌套類型

使一個(gè)已有類型符合某個(gè)協(xié)議

*/

/**語(yǔ)法:關(guān)鍵字extension

extension SomeType {

//加到SomeType的新功能寫在這里

}

一個(gè)擴(kuò)展可以擴(kuò)展一個(gè)已有類型搓谆,使其能夠適配一個(gè)或多個(gè)協(xié)議,語(yǔ)法格式如下

extension SomeType: SomeProtocol, AnotherProctocol {

//協(xié)議實(shí)現(xiàn)寫到這里

}

*/

// (1)計(jì)算型屬性:擴(kuò)展可以向已有類型添加計(jì)算型實(shí)例屬性和計(jì)算型類型屬性豪墅。

letaddition =3.add

print("加法運(yùn)算后的值:\(addition)")//輸出:加法運(yùn)算后的值:103

// (2)構(gòu)造器:擴(kuò)展可以向已有類型添加新的構(gòu)造器泉手。

//這可以讓你擴(kuò)展其它類型,將你自己的定制類型作為構(gòu)造器參數(shù)偶器,或者提供該類型的原始實(shí)現(xiàn)中沒(méi)有包含的額外初始化選項(xiàng)斩萌。

//擴(kuò)展可以向類中添加新的便利構(gòu)造器init(),但是它們不能向類中添加新的指定構(gòu)造器或析構(gòu)函數(shù)deinit()

// (3)方法:擴(kuò)展可以向已有類型添加新的實(shí)例方法和類型方法屏轰。

4.topics ({

print("擴(kuò)展模塊內(nèi)")

})

1.topics({

print("內(nèi)型轉(zhuǎn)換模塊內(nèi)")

})

2.topics {

print("222222")

}

// (4)可變實(shí)例方法:通過(guò)擴(kuò)展添加的實(shí)例方法也可以修改該實(shí)例本身颊郎。

//結(jié)構(gòu)體和枚舉類型中修改self或其屬性的方法必須將該實(shí)例方法標(biāo)注為mutating,正如來(lái)自原始實(shí)現(xiàn)的修改方法一樣

vartrail1 =2.3

trail1.square()

print("圓的面積:\(trail1)")

// (5)下標(biāo):擴(kuò)展可以向一個(gè)已有類型添加新下標(biāo)霎苗。

print(12[0])//輸出2

// (6)嵌套類型:擴(kuò)展可以向已有的類姆吭、結(jié)構(gòu)體和枚舉添加新的嵌套類型:

//

//協(xié)議規(guī)定了用來(lái)實(shí)現(xiàn)某一特定功能所必需的方法和屬性。任意能夠滿足協(xié)議要求的類型被稱為遵循(conform)這個(gè)協(xié)議唁盏。

//類内狸,結(jié)構(gòu)體或枚舉類型都可以遵循協(xié)議,并提供具體實(shí)現(xiàn)來(lái)完成協(xié)議定義的方法和功能

/**語(yǔ)法:

protocol SomeProtocol {

//協(xié)議內(nèi)容

}

*//**

要使類遵循某個(gè)協(xié)議升敲,需要在類型名稱后加上協(xié)議名稱,中間以冒號(hào):分隔轰传,作為類型定義的一部分驴党。遵循多個(gè)協(xié)議時(shí),各協(xié)議之間用逗號(hào),分隔获茬。

struct SomeStructure: FirstPotocol, AontherProtocol {

//結(jié)構(gòu)體內(nèi)容

}

如果類在遵循協(xié)議的同時(shí)擁有父類港庄,應(yīng)該將父類名放在協(xié)議名之前,以逗號(hào)分隔恕曲。

class SomeClass: SomeSuperClass, FirstPotocol, AontherProtocol {

//類內(nèi)容

}

*/

// (1)對(duì)屬性的規(guī)定:協(xié)議用于指定特定的實(shí)例屬性或類屬性鹏氧,而不用指定是存儲(chǔ)型屬性或計(jì)算型屬性。此外還必須指明是只讀的還是可讀可寫的

//協(xié)議中的通常用var來(lái)聲明變量屬性佩谣,在類型聲明后加上{ set get }來(lái)表示屬性是可讀可寫的把还,只讀屬性則用{

get }來(lái)表示。

letstudentH = classc()

studentH.stname ="swift"

studentH.marks =98

studentH.marksseucred()

print(studentH.marks, studentH.result, studentH.present, studentH.subject, studentH.stname)

// (2)對(duì)Mutating方法的規(guī)定:有時(shí)需要在方法中改變它的實(shí)例茸俭。

//例如吊履,值類型(結(jié)構(gòu)體,枚舉)的實(shí)例方法中调鬓,將mutating關(guān)鍵字作為函數(shù)的前綴艇炎,寫在func之前,表示可以在該方法中修改它所屬的實(shí)例及其實(shí)例屬性的值腾窝。

varres = days.wed

res.show()

// (3)對(duì)構(gòu)造器的規(guī)定:協(xié)議可以要求它的遵循者實(shí)現(xiàn)指定的構(gòu)造器缀踪。

//你可以像書(shū)寫普通的構(gòu)造器那樣居砖,在協(xié)議的定義里寫下構(gòu)造器的聲明,但不需要寫花括號(hào)和構(gòu)造器的實(shí)體驴娃,語(yǔ)法如下:

/**語(yǔ)法

protocol SomeProtocol {

init(someParameter: Int)

}

*/

// (3)協(xié)議構(gòu)造器規(guī)定在類中的實(shí)現(xiàn):

//你可以在遵循該協(xié)議的類中實(shí)現(xiàn)構(gòu)造器奏候,并指定其為類的指定構(gòu)造器或者便利構(gòu)造器。在這兩種情況下托慨,你都必須給構(gòu)造器實(shí)現(xiàn)標(biāo)上"required"修飾符:

/**語(yǔ)法: ? required

class SomeClass: SomeProtocol {

required init(someParameter: Int) {

//構(gòu)造器實(shí)現(xiàn)

}

}

*/

//使用required修飾符可以保證:所有的遵循該協(xié)議的子類鼻由,同樣能為構(gòu)造器規(guī)定提供一個(gè)顯式的實(shí)現(xiàn)或繼承實(shí)現(xiàn)。

// required,override :如果一個(gè)子類重寫了父類的指定構(gòu)造器厚棵,并且該構(gòu)造器遵循了某個(gè)協(xié)議的規(guī)定蕉世,那么該構(gòu)造器的實(shí)現(xiàn)需要被同時(shí)標(biāo)示required和override修飾符:

letaf = mClass.init(aprot:23)

letafshow = sClass.init(no1:32, no2:31)

print("af is :\(af.no1)","afshow

is\(afshow.no1)")

//(4)協(xié)議類型:盡管協(xié)議本身并不實(shí)現(xiàn)任何功能,但是協(xié)議可以被當(dāng)做類型來(lái)使用

/**協(xié)議可以像其他普通類型一樣使用婆硬,使用場(chǎng)景:

作為函數(shù)狠轻、方法或構(gòu)造器中的參數(shù)類型或返回值類型

作為常量、變量或?qū)傩缘念愋?/p>

作為數(shù)組彬犯、字典或其他容器中的元素類型

*/

varitemsss = [10,20,30].generate()

whileletx = itemsss.next() {

print(x)

}//輸出10 20 30

forlistsin[1,2,3].map({iini*5}) {

print(lists)

}//輸出5? 10? 15

// (5)在擴(kuò)展中添加協(xié)議成員

//我們可以可以通過(guò)擴(kuò)展來(lái)擴(kuò)充已存在類型(類向楼,結(jié)構(gòu)體,枚舉等)谐区。擴(kuò)展可以為已存在的類型添加屬性湖蜕,方法,下標(biāo)腳本宋列,協(xié)議等成員昭抒。

// (6)協(xié)議的繼承:協(xié)議能夠繼承一個(gè)或多個(gè)其他協(xié)議,可以在繼承的協(xié)議基礎(chǔ)上增加新的內(nèi)容要求炼杖。

/**協(xié)議的繼承語(yǔ)法與類的繼承相似灭返,多個(gè)被繼承的協(xié)議間用逗號(hào)分隔:

protocol InheritingProtocol: SomeProtocol, AnotherProtocol {

//協(xié)議定義

}

*/

// (7)類專屬協(xié)議: class,你可以在協(xié)議的繼承列表中,通過(guò)添加class關(guān)鍵字,限制協(xié)議只能適配到類(class)類型。

/**該class關(guān)鍵字必須是第一個(gè)出現(xiàn)在協(xié)議的繼承列表中坤邪,其后熙含,才是其他繼承協(xié)議。格式如下:

protocol SomeClassOnlyProtocol: class, SomeInheritedProtocol {

//協(xié)議定義

}

*/

// (8)協(xié)議合成: Swift支持合成多個(gè)協(xié)議艇纺,這在我們需要同時(shí)遵循多個(gè)協(xié)議時(shí)非常有用怎静。

/**語(yǔ)法格式:

protocol

*/

funcshowand(celebrator:Stname&Stage) {

print("\(celebrator.name) is\(celebrator.age)

years old")

}

letsnameaa = PerSonsss.init(name:"Priya", age:20)

showand(snameaa)//輸出結(jié)果Priya is 20 years old

// (9)檢驗(yàn)協(xié)議的一致性:你可以使用is和as操作符來(lái)檢查是否遵循某一協(xié)議或強(qiáng)制轉(zhuǎn)化為某一類型。

/**

is操作符用來(lái)檢查實(shí)例是否遵循了某個(gè)協(xié)議黔衡。

as?返回一個(gè)可選值消约,當(dāng)實(shí)例遵循協(xié)議時(shí),返回該協(xié)議類型;否則返回nil员帮。

as用以強(qiáng)制向下轉(zhuǎn)型或粮,如果強(qiáng)轉(zhuǎn)失敗,會(huì)引起運(yùn)行時(shí)錯(cuò)誤捞高。

*/

letobjectsprotocol:[AnyObject] = [

Circle(radius:2.0),

Country(area:234),

Animal(legs:23)]

forobjectinobjectsprotocol {

ifletobjectAraea = objectas?HasArea{

print("面積是:\(objectAraea.area)")

}else{

print("沒(méi)有面積")

}

}//輸出結(jié)果面積是:12.566面積是:234.0沒(méi)有面積

//

// swift提供了泛型讓你寫出靈活且可重用的函數(shù)和類型氯材,swift標(biāo)準(zhǔn)庫(kù)是通過(guò)泛型代碼構(gòu)建出來(lái)的渣锦,swift的數(shù)組和字典都是泛型,

//你可以創(chuàng)建一個(gè)Int數(shù)組氢哮,也可創(chuàng)建一個(gè)String數(shù)組袋毙,或者甚至于可以是任何其他Swift的類型數(shù)據(jù)數(shù)組。

//以下實(shí)例是一個(gè)非泛型函數(shù)exchange用來(lái)交換兩個(gè)Int值:

funcexchange( a:inoutInt, b:inoutInt)

{

lettemp = a

a = b

b = temp

}

varnumb1 =20

varnumb2 =30

print("交換前數(shù)據(jù):\(numb1)和\(numb2)")

exchange(&numb1, b: &numb2)

print("交換后數(shù)據(jù):\(numb1)和\(numb2)")

//泛型函數(shù)可以訪問(wèn)任何類型冗尤,如Int或String

//以下實(shí)例是一個(gè)泛型函數(shù)exchange用來(lái)交換兩個(gè)Int和String值:

funcexchangefanxing( a:inoutT, b:inoutT)

{

lettemp = a

a = b

b = temp

}

varexcnumb1 =100

varexcnumb2 =200

print("交換前數(shù)據(jù):\(excnumb1)和\(excnumb2)")

exchangefanxing(&excnumb1, b: &excnumb2)

print("交換后數(shù)據(jù):\(excnumb1)和\(excnumb2)")

varexcstr1 ="AAA"

varexcstr2 ="BBB"

print("交換前數(shù)據(jù):\(excstr1)和\(excstr2)")

exchangefanxing(&excstr1, b: &excstr2)

print("交換后數(shù)據(jù):\(excstr1)和\(excstr2)")

/**

這個(gè)函數(shù)的泛型版本使用了占位類型名字(通常此情況下用字母T來(lái)表示)來(lái)代替實(shí)際類型名(如Int听盖、String或Double)。

占位類型名沒(méi)有提示T必須是什么類型裂七,但是它提示了a和b必須是同一類型T皆看,而不管T表示什么類型。

只有exchange(_:_:)函數(shù)在每次調(diào)用時(shí)所傳入的實(shí)際類型才能決定T所代表的類型背零。

另外一個(gè)不同之處在于這個(gè)泛型函數(shù)名后面跟著的占位類型名字(T)是用尖括號(hào)括起來(lái)的()腰吟。

這個(gè)尖括號(hào)告訴Swift那個(gè)T是exchange(_:_:)函數(shù)所定義的一個(gè)類型。因?yàn)門是一個(gè)占位命名類型徙瓶,Swift不會(huì)去查找命名為T的實(shí)際類型毛雇。

*/

// (1)泛型類型: Swift允許你定義你自己的泛型類型。

//自定義類侦镇、結(jié)構(gòu)體和枚舉作用于任何類型灵疮,如同Array和Dictionary的用法。

vartos = TOS()

tos.push("swift")

print(tos.items)

tos.push("泛型")

print(tos.items)

letdeleteos = tos.pop()

print(deleteos,"aaa")

// (2)擴(kuò)展泛型類型: extension,你并不需要在擴(kuò)展的定義中提供類型參數(shù)列表

//原始類型定義中聲明的類型參數(shù)列表在擴(kuò)展里是可以使用的壳繁,并且這些來(lái)自原始類型中的參數(shù)名稱會(huì)被用作原始定義中類型參數(shù)的引用震捣。

ifletfirst = tos.first {

print("棧頂部:\(first)")

}

// (3)類型約束:指定了一個(gè)必須繼承自指定類的類型參宿,或者遵循一個(gè)特定的協(xié)議或協(xié)議構(gòu)成

/**類型約束語(yǔ)法:

可以寫一個(gè)在一個(gè)類型參數(shù)名后面的類型約束氮趋,通過(guò)冒號(hào)分割伍派,來(lái)作為類型參數(shù)鏈的一部分江耀。這種作用于泛型函數(shù)的類型約束的基礎(chǔ)語(yǔ)法如下所示:

func someFunction(someT: T, someU: U) {

//這里是函數(shù)主體

}

*/

funcfindStringIndex(array: [String],_valueToFind:String)

->Int? {

for(index, value)inarray.enumerate() {

ifvalue == valueToFind {

returnindex

}

}

returnnil

}

letstringsss = ["cat","dog","llama","parakeet","terrapin"]

ifletfoundIndex = findStringIndex(stringsss,"llama") {

print("llama的下標(biāo)是\(foundIndex)")

}

// (4)關(guān)聯(lián)類型實(shí)例: typealias關(guān)鍵字用來(lái)設(shè)置關(guān)聯(lián)類型

//定義一個(gè)協(xié)議時(shí)剩胁,有的時(shí)候聲明一個(gè)或多個(gè)關(guān)聯(lián)類型作為協(xié)議定義的一部分是非常有用的。

vartos1 = TOSCon()

tos1.push("swift1")

print(tos1.items)

tos1.push("泛型1")

print(tos1.items)

tos1.push("參數(shù)類型1")

print(tos1.items)

tos1.push("類型參數(shù)名1")

print(tos1.items)

// (5)Where語(yǔ)句

/**

類型約束能夠確保類型符合泛型函數(shù)或類的定義約束祥国。

你可以在參數(shù)列表中通過(guò)where語(yǔ)句定義參數(shù)的約束昵观。

你可以寫一個(gè)where語(yǔ)句,緊跟在在類型參數(shù)列表后面舌稀,where語(yǔ)句后跟一個(gè)或者多個(gè)針對(duì)關(guān)聯(lián)類型的約束啊犬,以及(或)一個(gè)或多個(gè)類型和關(guān)聯(lián)類型間的等價(jià)(equality)關(guān)系。

// swift 3.0之前版本寫法

func allItemsMatchContainer, C2:Container

where C1.ItemType == C2.ItemType, C1.ItemType: Equatable>(someContainer: C1, anotherContainer: C2) -> Bool {

*/

funcallItemsMatch(someContainer: C1,

anotherContainer: C2) -> Bool

whereC1.ItemType==C2.ItemType,C1.ItemType:Equatable{

//檢查兩個(gè)Container的元素個(gè)數(shù)是否相同

ifsomeContainer.count != anotherContainer.count {

returnfalse

}

//檢查兩個(gè)Container相應(yīng)位置的元素彼此是否相等

foriin0..

ifsomeContainer[i] != anotherContainer[i] {

returnfalse

}

}

//匹配所有項(xiàng)壁查,返回true

returntrue

}

varttt = Stack()

ttt.push("Swift2")

print(ttt.items)

ttt.push("泛型2")

print(ttt.items)

ttt.push("Where語(yǔ)句2")

print(ttt.items)

vareos = ["Swift","泛型","Where語(yǔ)句"]

print(eos)

//

/** swift為代碼中的實(shí)體提供了三種不同的訪問(wèn)級(jí)別:public觉至、internal、private

訪問(wèn)級(jí)別定義

Public可以訪問(wèn)自己模塊中源文件里的任何實(shí)體睡腿,別人也可以通過(guò)引入該模塊來(lái)訪問(wèn)源文件里的所有實(shí)體语御。

Internal可以訪問(wèn)自己模塊中源文件里的任何實(shí)體峻贮,但是別人不能訪問(wèn)該模塊中源文件里的實(shí)體。

Private只能在當(dāng)前源文件中使用的實(shí)體应闯,稱為私有實(shí)體纤控。

*/// public為最高級(jí)訪問(wèn)級(jí)別,private為最低級(jí)訪問(wèn)級(jí)別

/**語(yǔ)法:

public class SomePublicClass ()

Internal calss SomeInternalClass ()

private class SomePrivareClass ()

public var somePlubilcVariable = 0

Internal let someInteralConstant = 0

private func somePrivateFunction() {}

*///除非有特殊的說(shuō)明碉纺,否則實(shí)體都使用默認(rèn)的訪問(wèn)級(jí)別internal船万。

// (1)函數(shù)類型訪問(wèn)權(quán)限:函數(shù)的訪問(wèn)級(jí)別需要根據(jù)該函數(shù)的參數(shù)類型和返回類型的訪問(wèn)級(jí)別得出。

/**下面的例子定義了一個(gè)名為someFunction全局函數(shù)骨田,并且沒(méi)有明確地申明其訪問(wèn)級(jí)別

func someFunction() -> (SomeInternalClass, SomePrivareClass) {

//函數(shù)實(shí)體

}

函數(shù)中其中一個(gè)類SomeInternalClass的訪問(wèn)級(jí)別是internal耿导,另一個(gè)SomePrivateClass的訪問(wèn)級(jí)別是private。所以根據(jù)元組訪問(wèn)級(jí)別的原則盛撑,該元組的訪問(wèn)級(jí)別是private碎节。

因?yàn)樵摵瘮?shù)返回類型的訪問(wèn)級(jí)別是private,所以你必須使用private修飾符抵卫,明確的聲明該函數(shù):

private func someFunction() -> (SomeInternalClass, SomePrivateClass) {

//函數(shù)實(shí)現(xiàn)

}

將該函數(shù)申明為public或internal狮荔,或者使用默認(rèn)的訪問(wèn)級(jí)別internal都是錯(cuò)誤的。

*/

// (2)枚舉類型訪問(wèn)權(quán)限:枚舉中成員的訪問(wèn)級(jí)別繼承自該枚舉介粘,你不能為枚舉中的成員單獨(dú)申明不同的訪問(wèn)級(jí)別殖氏。

varstuAll = StudentAll.Name("swift")

varstualla = StudentAll.Mark(99,98,97)

switchstualla {

case.Name(let stuName):

print("學(xué)生:\(stuName)")

case.Mark(let math, let English, let Chines):

print("學(xué)生的成績(jī):\(math),\(English),\(Chines)")

}

// (3)子類訪問(wèn)權(quán)限:子類的訪問(wèn)級(jí)別不得高于父類的訪問(wèn)級(jí)別。比如說(shuō)姻采,父類的訪問(wèn)級(jí)別是internal雅采,子類的訪問(wèn)級(jí)別就不能申明為public。

letsup = superClassss()

sup.show()

letsub = ssClassss()

sub.show

// (4)常量慨亲、變量婚瓜、屬性、下標(biāo)訪問(wèn)權(quán)限:常量刑棵、變量巴刻、屬性不能擁有比它們的類型更高的訪問(wèn)級(jí)別。下標(biāo)也不能擁有比索引類型或返回類型更高的訪問(wèn)級(jí)別蛉签。

// private var privateInstance = SomePrivateClass()

// (5)Getter Setter訪問(wèn)權(quán)限:常量胡陪、變量、屬性碍舍、下標(biāo)索引的Getters和Setters的訪問(wèn)級(jí)別繼承自它們所屬成員的訪問(wèn)級(jí)別

// Setter的訪問(wèn)級(jí)別可以低于對(duì)應(yīng)的Getter的訪問(wèn)級(jí)別柠座,這樣就可以控制變量、屬性或下標(biāo)索引的讀寫權(quán)限片橡。

letnewCounter = samplegm()

newCounter.counter =100

newCounter.counter =800

//輸出結(jié)果:計(jì)數(shù)器: 100新增加數(shù)量100計(jì)數(shù)器: 800新增加數(shù)量700

// (6)構(gòu)造器和默認(rèn)構(gòu)造器訪問(wèn)權(quán)限:

/**

初始化:我們可以給自定義的初始化方法申明訪問(wèn)級(jí)別妈经,但是要不高于它所屬類的訪問(wèn)級(jí)別。但必要構(gòu)造器例外,它的訪問(wèn)級(jí)別必須和所屬類的訪問(wèn)級(jí)別相同

如同函數(shù)或方法參數(shù)吹泡,初始化方法參數(shù)的訪問(wèn)級(jí)別也不能低于初始化方法的訪問(wèn)級(jí)別录煤。

默認(rèn)初始化方法:Swift為結(jié)構(gòu)體、類都提供了一個(gè)默認(rèn)的無(wú)參初始化方法荞胡,用于給它們的所有屬性提供賦值操作妈踊,但不會(huì)給出具體值。

默認(rèn)初始化方法的訪問(wèn)級(jí)別與所屬類型的訪問(wèn)級(jí)別相同泪漂。

*/

letababab = classAa()

letbabab = clssAb()//輸出結(jié)果:10? 30? 10

// (7)協(xié)議訪問(wèn)權(quán)限:如果想為一個(gè)協(xié)議明確的申明訪問(wèn)級(jí)別廊营,那么需要注意一點(diǎn),就是你要確保該協(xié)議只在你申明的訪問(wèn)級(jí)別作用域中使用萝勤。

//如果你定義了一個(gè)public訪問(wèn)級(jí)別的協(xié)議露筒,那么實(shí)現(xiàn)該協(xié)議提供的必要函數(shù)也會(huì)是public的訪問(wèn)級(jí)別。這一點(diǎn)不同于其他類型敌卓,比如慎式,public訪問(wèn)級(jí)別的其他類型,他們成員的訪問(wèn)級(jí)別為internal趟径。

// (8)擴(kuò)展訪問(wèn)權(quán)限:擴(kuò)展成員應(yīng)該具有和原始類成員一致的訪問(wèn)級(jí)別瘪吏。比如你擴(kuò)展了一個(gè)公共類型,那么你新加的成員應(yīng)該具有和原始成員一樣的默認(rèn)的internal訪問(wèn)級(jí)別蜗巧。

//或者掌眠,你可以明確申明擴(kuò)展的訪問(wèn)級(jí)別(比如使用private extension)給該擴(kuò)展內(nèi)所有成員申明一個(gè)新的默認(rèn)訪問(wèn)級(jí)別。這個(gè)新的默認(rèn)訪問(wèn)級(jí)別仍然可以被單獨(dú)成員所申明的訪問(wèn)級(jí)別所覆蓋

// (9)泛型訪問(wèn)權(quán)限:泛型類型或泛型函數(shù)的訪問(wèn)級(jí)別取泛型類型幕屹、函數(shù)本身蓝丙、泛型類型參數(shù)三者中的最低訪問(wèn)級(jí)別。

// (10)類型別名:任何你定義的類型別名都會(huì)被當(dāng)作不同的類型望拖,以便于進(jìn)行訪問(wèn)控制渺尘。一個(gè)類型別名的訪問(wèn)級(jí)別不可高于原類型的訪問(wèn)級(jí)別。

//注意:這條規(guī)則也適用于為滿足協(xié)議一致性而給相關(guān)類型命名別名的情況说敏。

//

//

//閉包(Closures)是自包含的功能代碼塊鸥跟,可以在代碼中使用或者用來(lái)作為參數(shù)傳值。

//全局函數(shù)和嵌套函數(shù)其實(shí)就是特殊的閉包像云。

/**閉包形式有:

全局函數(shù)嵌套函數(shù)閉包表達(dá)式

有名字但不能捕獲任何值锌雀。有名字蚂夕,也能捕獲封閉函數(shù)內(nèi)的值迅诬。無(wú)名閉包,使用輕量級(jí)語(yǔ)法婿牍,可以根據(jù)上下文環(huán)境捕獲值侈贷。

*/

/** Swift中的閉包有很多優(yōu)化的地方:

根據(jù)上下文推斷參數(shù)和返回值類型

從單行表達(dá)式閉包中隱式返回(也就是閉包體只有一行代碼,可以省略return)

可以使用簡(jiǎn)化參數(shù)名,如$0, $1(從0開(kāi)始俏蛮,表示第i個(gè)參數(shù)...)

提供了尾隨閉包語(yǔ)法(Trailing closure syntax)

語(yǔ)法:

{(parameters) -> return type in

statements

}

*/

letdivde = {(val1:Int, val2:Int) ->Intin

returnval1 / val2

}

letresult1 = divde(200,20)

print(result1)//輸出結(jié)果:10

// (1)閉包表達(dá)式:閉包表達(dá)式是一種利用簡(jiǎn)潔語(yǔ)法構(gòu)建內(nèi)聯(lián)閉包的方式撑蚌。

// sort函數(shù):

letnameall = ["AT","AE","D","S","BE"]

funcbackwards(s1:String, s2:String)

->Bool{//使用普通函數(shù)(或內(nèi)嵌函數(shù))提供排序功能,閉包函數(shù)類型需為(String,

String) -> Bool。

returns1 > s2

}

varreversed = nameall.sort(backwards)

print(reserved)//輸出結(jié)果:["S", "D", "BE", "AT", "AE"]

// (2)參數(shù)名稱縮寫:Swift自動(dòng)為內(nèi)聯(lián)函數(shù)提供了參數(shù)名稱縮寫功能搏屑,您可以直接通過(guò)$0,$1,$2來(lái)順序調(diào)用閉包的參數(shù)争涌。

varreversed1 = nameall.sort( { $0 > $1 } )// $0和$1表示閉包中第一個(gè)和第二個(gè)String類型的參數(shù)。

print(reversed1)//輸出:["S", "D", "BE", "AT", "AE"]

// (3)運(yùn)算符函數(shù):實(shí)際上還有一種更簡(jiǎn)短的方式來(lái)撰寫上面例子中的閉包表達(dá)式辣恋。

varreversed2 = nameall.sort(>)// Swift的String類型定義了關(guān)于大于號(hào)(>)的字符串實(shí)現(xiàn)亮垫,其作為一個(gè)函數(shù)接受兩個(gè)String類型的參數(shù)并返回Bool類型的值。而這正好與sort(_:)方法的第二個(gè)參數(shù)需要的函數(shù)類型相符合伟骨。因此饮潦,您可以簡(jiǎn)單地傳遞一個(gè)大于號(hào),Swift可以自動(dòng)推斷出您想使用大于號(hào)的字符串函數(shù)實(shí)現(xiàn):

print(reversed2)//輸出:["S", "D", "BE", "AT", "AE"]

// (4)尾隨閉包:尾隨閉包是一個(gè)書(shū)寫在函數(shù)括號(hào)之后的閉包表達(dá)式携狭,函數(shù)支持將其作為最后一個(gè)參數(shù)調(diào)用

/**

func someFunctionThatTakesAClosure(closure: () -> Void) {

//函數(shù)體部分

}

//以下是不使用尾隨閉包進(jìn)行函數(shù)調(diào)用

someFunctionThatTakesAClosure({

//閉包主體部分

})

//以下是使用尾隨閉包進(jìn)行函數(shù)調(diào)用

someFunctionThatTakesAClosure() {

//閉包主體部分

}

//注意:如果函數(shù)只需要閉包表達(dá)式一個(gè)參數(shù)继蜡,當(dāng)您使用尾隨閉包時(shí),您甚至可以把()省略掉逛腿。var

reversed3 = nameall.sort { $0 > $1}

*/

varreversed3 = nameall.sort() { $0 > $1}

print(reversed3)//輸出:["S", "D", "BE", "AT", "AE"]

// (5)捕獲值:

// (6)閉包是引用類型:

//

// Optional Chaining,是一種可以請(qǐng)求和調(diào)用屬性稀并、方法和子腳本的過(guò)程,用于請(qǐng)求或調(diào)用的目標(biāo)可能為nil单默。

/**可選鏈返回兩個(gè)值:

如果目標(biāo)有值稻轨,調(diào)用就會(huì)成功,返回該值

如果目標(biāo)為nil雕凹,調(diào)用將返回nil

*///多次請(qǐng)求或調(diào)用可以被鏈接成一個(gè)鏈殴俱,如果任意一個(gè)節(jié)點(diǎn)為nil將導(dǎo)致整條鏈?zhǔn)?/p>

// (1)可選鏈可替代強(qiáng)制解析:? ? !

// (2)為可選鏈定義模型類:你可以使用可選鏈來(lái)多層調(diào)用屬性,方法枚抵,和下標(biāo)腳本线欲。這讓你可以利用它們之間的復(fù)雜模型來(lái)獲取更底層的屬性,并檢查是否可以成功獲取此類底層屬性

// (3)通過(guò)可選鏈調(diào)用方法:你可以使用可選鏈的來(lái)調(diào)用可選值的方法并檢查方法調(diào)用是否成功汽摹。即使這個(gè)方法沒(méi)有返回值李丰,你依然可以使用可選鏈來(lái)達(dá)成這一目的。

// (4)使用可選鏈調(diào)用下標(biāo)腳本:

// (5)通過(guò)可選鏈接調(diào)用來(lái)訪問(wèn)下標(biāo):

// (6)訪問(wèn)可選類型的下標(biāo):如果下標(biāo)返回可空類型值逼泣,比如Swift中Dictionary的key下標(biāo)趴泌。可以在下標(biāo)的閉合括號(hào)后面放一個(gè)問(wèn)號(hào)來(lái)鏈接下標(biāo)的可空返回值:

// (7)連接多層鏈接:

// (8)對(duì)返回可選值的函數(shù)進(jìn)行鏈接:我們還可以通過(guò)可選鏈接來(lái)調(diào)用返回可空值的方法拉庶,并且可以繼續(xù)對(duì)可選值進(jìn)行鏈接嗜憔。

}

overridefuncdidReceiveMemoryWarning() {//重寫父類方法

super.didReceiveMemoryWarning()

// Dispose of any resources that can be recreated.

}

/*************實(shí)例方法**************/

funcaAddB(a:Int, b:Int) ->Int{//(實(shí)例方法)

returna+b

}

varcountA =0

funccountADD(addCount:Int) {//(實(shí)例方法)

countA += addCount

}

}

//-----------------------------------------------------------------------------------------------------------------//

//-----------------------------------------------------------------------------------------------------------------//

classViewController2:UIViewController{

privatevardaysdays = ["Sun","Mun","Tue","Wed","Thu","Fri","Sat"]

subscript(index:Int) ->String{

get{

returndaysdays[index]//聲明下標(biāo)腳本語(yǔ)言

}

set(newValue) {

self.daysdays[index] = newValue//執(zhí)行賦值操作

}

}

}

//-----------------------------------------------------------------------------------------------------------------//

//-----------------------------------------------------------------------------------------------------------------//

classStudentDetails {// (1)基類,沒(méi)有繼承其它類的類,稱之為基類(Base

Class)氏仗。

varEnglish =99//默認(rèn)值吉捶,

varMath:Int{

returnEnglish -5

}

funcrecordMarks() {

print("父類中的方法>>>>>>")

}

}

classTom:StudentDetails{// (2)子類,子類指的是在一個(gè)已有類的基礎(chǔ)上創(chuàng)建一個(gè)新的類

varChines =10

overridevarEnglish:Int{

didSet{

Chines = English /2

}

}

overridevarMath:Int{// get-only

returnsuper.Math -5

}

overridefuncrecordMarks() {

super.recordMarks()

print("子類中的重寫>>>>>>>")

}

}

//-----------------------------------------------------------------------------------------------------------------//

//-----------------------------------------------------------------------------------------------------------------//

//(1)構(gòu)造過(guò)程

classShoppingListItem {//以下實(shí)例中,ShoppingListItem類中的所有屬性都有默認(rèn)值,且它是沒(méi)有父類的基類呐舔,它將自動(dòng)獲得一個(gè)可以為所有屬性設(shè)置默認(rèn)值的默認(rèn)構(gòu)造器

varname :String?

varquantity =1

varpurchased =false

}

//(2)指定構(gòu)造器實(shí)例

classMooncake {

varhuamei:String//局部存儲(chǔ)變量

init(huaMei:String) {

self.huamei = huaMei//初始化

}

}

classRonglang:Mooncake{

varronglang :String//新的子類存儲(chǔ)變量

init(huaMei:String, rongLang:String)

{//初始化類中提供的所有屬性币励,并根據(jù)父類鏈往上調(diào)用父類的構(gòu)造器來(lái)實(shí)現(xiàn)父類的初始化

self.ronglang = rongLang//初始化

super.init(huaMei: huaMei)//初始化超類

}

}

// (3)便利構(gòu)造器實(shí)例

classcarCalss {

varaodi:String//局部存儲(chǔ)變量

init(aoDI:String) {

self.aodi = aoDI//初始化

}

}

classAODIClass:carCalss{

vardazhong:String

init(aoDI:String, daZhong:String) {

self.dazhong = daZhong

super.init(aoDI: aoDI)

}

//便利方法只需要一個(gè)參數(shù)

overrideconvenienceinit(aoDI:String)

{

self.init(aoDI: aoDI, daZhong:"")

}

}

// (4)構(gòu)造器的繼承和重載

classWineClass {

varredWine ="紅酒"

vardesccription:String{

return"\(redWine)不錯(cuò)!"

}

}

classREDWineClass:WineClass{

overrideinit() {//重載構(gòu)造器

super.init()

redWine ="紅酒名酒珊拼。食呻。。"

}

}

// (5)指定構(gòu)造器和便利構(gòu)造器繼承實(shí)例

classGameClass {

varmobileGames:String

init(mobilegame:String) {

self.mobileGames = mobilegame

}

convenienceinit() {

self.init(mobilegame:"逐鹿天下手游")

}

}

classMobileGameClass:GameClass{

varzhuluGame :String

init(moblegame:String, zhulu:String) {

self.zhuluGame = zhulu

super.init(mobilegame: moblegame)

}

overrideconvenienceinit(mobilegame:String)

{

self.init(moblegame: mobilegame, zhulu:"逐鹿")

}

}

// (6)可失敗構(gòu)造器

classplanet {

varname :String

init(name:String) {

self.name = name;

}

convenienceinit() {

self.init(name:"[No Planets]")

}

}

classplanets:planet{

varcount :Int

init(name:String, count:Int) {

self.count = count

super.init(name: name)

}

overrideconvenienceinit(name:String)

{

self.init(name: name, count:1)

}

}

// (7)可失敗構(gòu)造器init!

structStuRecord {

letstname :String

init!(stname:String) {

ifstname.isEmpty {

returnnil

}

self.stname = stname

}

}

// (8)析構(gòu)過(guò)程

varcounter =0;//引用計(jì)數(shù)器

classBaseClass {

init() {

counter +=1;

}

deinit{

counter -=1;

}

}

// (9)循環(huán)強(qiáng)引用

classSignClass {

letname :String

init(name :String) {

self.name = name

}

varbaseSs :SSClass?

deinit{

print(" #\(name)被析構(gòu)")//循環(huán)強(qiáng)引用澎现,不會(huì)被調(diào)用

}

}

classSSClass {

letnumber :Int

init(number:Int) {

self.number = number

}

varbaseSign :SignClass?

deinit{

print("SSClass #\(number)被析構(gòu)")//循環(huán)強(qiáng)引用搁进,不會(huì)被調(diào)用

}

}

// (10)弱引用實(shí)例

classModule {

letname :String

init(name:String) {

self.name = name

}

varsub :SubModul?

deinit{

print("\(name)主模塊被析構(gòu)")//弱引用抵怎,會(huì)被調(diào)用

}

}

classSubModul {

letnumber :Int

init(number :Int) {

self.number = number

}

weakvartopic :Module?

deinit{

print("子模塊topic數(shù)為\(number)")//弱引用废境,會(huì)被調(diào)用

}

}

// (10)無(wú)主引用實(shí)例

classStudentPeter {

letname :String

varsection :MarkPeter?

init(name:String) {

self.name = name

}

deinit{

print("析構(gòu)函數(shù):學(xué)生姓名:\(name)")//無(wú)主引用长搀,會(huì)被調(diào)用

}

}

classMarkPeter {

letmarks :Int

unownedletstname:StudentPeter

init(marks:Int, stname:StudentPeter) {

self.marks = marks

self.stname = stname

}

deinit{

print("析構(gòu)函數(shù):學(xué)生的分?jǐn)?shù):\(marks)")//無(wú)主引用逻淌,會(huì)被調(diào)用

}

}

// (11)閉包引起的循環(huán)強(qiáng)引用實(shí)例

classHTMLElement {

letname :String

lettext :String?

lazyvarasHTML: () ->String= {//閉包在其閉包體內(nèi)使用了self(引用了self.name和self.text)

iflettext =self.text

{//因此閉包捕獲了self曾撤,這意味著閉包又反過(guò)來(lái)持有了HTMLElement實(shí)例的強(qiáng)引用

return"<\(self.name)>\(text)<\(self.name)>"

}else{

return"<\(self.name)>"

}

}

lazyvarasasHTML: () ->String= {

[unownedself]in//無(wú)主引用是正確的解決循環(huán)強(qiáng)引用的方法

iflettext =self.text {

return"<\(self.name)>\(text)"

}else{

return"<\(self.name)

/>"

}

}

init(name:String, text:String?) {

self.name = name

self.text = text

}

deinit{

print("\(name) is being deinitalized")

}

}

// (12)擴(kuò)展

extensionInt{//a.下面的例子向Int類型添加了4個(gè)計(jì)算型實(shí)例屬性并擴(kuò)展其功能

varadd:Int{

returnself+100

}

varsub:Int{

returnself-10

}

varmul:Int{

returnself*10

}

vardiv:Int{

returnself/5

}

}

structsum {

varnum1 =100, num2 =200

}

structdiff {

varno1 =200, no2 =100

}

structmult {

vara = sum()

varb = diff()

}

extensionmult{//構(gòu)造器擴(kuò)展

init(x:sum, y:diff) {

_= x.num1 + x.num2

_= y.no1 + y.no2

}

}

extensionInt{//下面的例子向Int類型添加一個(gè)名為topics的新實(shí)例方法

functopics(summation: () -> ()) {

for_in0..

summation()

}

}

}

//下面的例子向Swift的Double類型添加了一個(gè)新的名為square的修改方法刚夺,來(lái)實(shí)現(xiàn)一個(gè)原始值的平方計(jì)算:mutating

extensionDouble{

mutatingfuncsquare() {

letPI =3.1415

self= PI *self*self

}

}

//以下例子向Swift內(nèi)建類型Int添加了一個(gè)整型下標(biāo)果录。該下標(biāo)[n]返回十進(jìn)制數(shù)字subscript

extensionInt{

subscript(var muttable:Int) ->Int{

varno1 =1

whilemuttable >0{

no1 +=10

muttable -=1

}

return(self/ no1) %10

}

}

// (13)協(xié)議

protocolclassa {

varmarks :Int{setget}

varresult :Bool{get}

funcattendance() ->String

funcmarksseucred() ->String

}

protocolcalssb:classa{

varpresent :Bool{getset}

varsubject :String{getset}

varstname :String{getset}

}

classclassc:calssb{

varmarks =96

letresult =true

varpresent =false

varsubject ="Swift協(xié)議"

varstname ="Protocol"

funcattendance() ->String{

return"The\(stname)

has secured 99% attendance"

}

funcmarksseucred() ->String{

return"\(stname) has scored\(marks)"

}

}

//對(duì)Mutating方法的規(guī)定

protocoldaysofaweek {

mutatingfuncshow()

}

enumdays:daysofaweek{

casesun, mon, tue, wed, thurs, fri, sat

mutatingfuncshow() {

switchself{

casesun:

self= sun

print("Sunday")

casemon:

self= mon

print("Monday")

default:

print("no such day !")

}

}

}

//對(duì)構(gòu)造器的規(guī)定

protocoltcpprotocol {

init(aprot:Int)

}

classtcpClass:tcpprotocol{// required,你可以在遵循該協(xié)議的類中實(shí)現(xiàn)構(gòu)造器咽袜,并指定其為類的指定構(gòu)造器或者便利構(gòu)造器

requiredinit(aprot:Int) {

}

}

classmClass {

varno1 :Int//局部變量

init(aprot:Int) {

self.no1 = aprot//初始化

}

}

classsClass:mClass,tcpprotocol{

varno2 :Int

init(no1:Int, no2:Int) {

self.no2 = no2

super.init(aprot: no1)

}

//因?yàn)樽裱瓍f(xié)議讹开,需要加上"required";因?yàn)槔^承自父類盅视,需要加上"override"

requiredoverrideconvenienceinit(aprot:Int)

{

self.init(no1:aprot, no2:0)

}

}

//協(xié)議類型

protocolGenerator {

associatedtypememebers

funcnext() ->memebers?

}

//在擴(kuò)展中添加協(xié)議成員

protocolAgeClassficationProtocol {

varage:Int{get}

funcagetype() ->String

}

classPersonss {

letfirstname :String

letlastname :String

varage :Int

init(firstname:String, lastname:String) {

self.firstname = firstname

self.lastname = lastname

self.age =10

}

}

extensionPersonss:AgeClassficationProtocol{

funcfullname() ->String{

varc :String

c = firstname +" "+ lastname

returnc

}

funcagetype() ->String{

switchage {

case0...2:

return"Baby"

case2...12:

return"Child"

case13...19:

return"Teenager"

caseletxwherex >65:

return"Elderly"

default:

return"Normal"

}

}

}

//協(xié)議的繼承

protocolsAgeClassProtocol:AgeClassficationProtocol{

}

//類專屬協(xié)議

protocolspecalClassProtocol:class,AgeClassficationProtocol{

}

//協(xié)議合成

protocolStname {

varname :String{get}

}

protocolStage {

varage :Int{get}

}

structPerSonsss:Stname,Stage{

varname:String

varage:Int

}

//檢驗(yàn)協(xié)議的一致性: is? as?? as

protocolHasArea {

vararea:Double{get}

}

classCircle:HasArea{//定義了Circle類,都遵循了HasArea協(xié)議

letPI? =3.1415

letradius :Double

vararea:Double{returnPI * radius * radius }

init(radius:Double) {

self.radius = radius

}

}

classCountry:HasArea{//定義了Country類旦万,都遵循了HasArea協(xié)議

vararea:Double

init(area:Double) {

self.area = area

}

}

classAnimal {// Animal是一個(gè)沒(méi)有實(shí)現(xiàn)HasArea協(xié)議的類

varlegs :Int

init(legs:Int) {

self.legs = legs

}

}

// (14)泛型

structTOS {

varitems = [T]()

mutatingfuncpush(item:T) {

items.append(item)

}

mutatingfuncpop() ->T{

returnitems.removeLast()

}

}

extensionTOS{//擴(kuò)展泛型類型

varfirst :T? {

returnitems.isEmpty ?nil: items[items.count -1]

}

}

//關(guān)聯(lián)類型實(shí)例

protocolContainer {

//定義了一個(gè)ItemType關(guān)聯(lián)類型

associatedtypeItemType

mutatingfuncappend(item:ItemType)

varcount :Int{get}

subscript(i:Int) ->ItemType{get}

}

structTOSCon:Container{//遵循Container協(xié)議的泛型TOSCon類型

varitems = [T]()

mutatingfuncpush(item:T) {

items.append(item)

}

mutatingfuncpop() ->T{

returnitems.removeLast()

}

mutatingfuncappend(item:T) {

self.push(item)

}

varcount:Int{

returnitems.count

}

subscript(i:Int) ->T{

returnitems[i]

}

}

//下面的例子定義了一個(gè)名為allItemsMatch的泛型函數(shù)闹击,用來(lái)檢查兩個(gè)Container實(shí)例是否包含相同順序的相同元素。

//如果所有的元素能夠匹配成艘,那么返回一個(gè)為true的Boolean值赏半,反之則為false。

structStack:Container{

varitems = [T]()

mutatingfuncpush(item:T) {

items.append(item)

}

mutatingfuncpop() ->T{

returnitems.removeLast()

}

mutatingfuncappend(item:T) {

self.push(item)

}

varcount:Int{

returnitems.count

}

subscript(i:Int) ->T{

returnitems[i]

}

}

//訪問(wèn)權(quán)限:

//枚舉類型訪問(wèn)權(quán)限:

publicenumStudentAll {//枚舉StudentAll被明確的申明為public級(jí)別淆两,那么它的成員Name断箫,Mark的訪問(wèn)級(jí)別同樣也是public:

caseName(String)

caseMark(Int, Int, Int)

}

//子類訪問(wèn)權(quán)限:子類訪問(wèn)級(jí)別不得高于父類訪問(wèn)級(jí)別

publicclasssuperClassss {

privatefuncshow() {

print("父類")

}

}

//訪問(wèn)級(jí)別不能低于超類internal > public

internalclassssClassss:superClassss{

overrideinternalfuncshow() {

print("子類")

}

}

// Getter Setter訪問(wèn)權(quán)限

classsamplegm {

privatevarcounter:Int=0{

willSet(newTotal) {

print("計(jì)數(shù)器:\(newTotal)")

}

didSet{

ifcounter > oldValue {

print("新增加數(shù)量:\(counter

- oldValue)")

}

}

}

}

//構(gòu)造器和默認(rèn)構(gòu)造器訪問(wèn)權(quán)限

classclassAa {

requiredinit() {

vara =10

print(a)

}

}

classclssAb:classAa{

requiredinit() {

varb =30

print(b)

}

}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市秋冰,隨后出現(xiàn)的幾起案子仲义,更是在濱河造成了極大的恐慌,老刑警劉巖剑勾,帶你破解...
    沈念sama閱讀 206,013評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件埃撵,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡虽另,警方通過(guò)查閱死者的電腦和手機(jī)暂刘,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,205評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)洲赵,“玉大人鸳惯,你說(shuō)我怎么就攤上這事〉迹” “怎么了芝发?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,370評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)苛谷。 經(jīng)常有香客問(wèn)我辅鲸,道長(zhǎng),這世上最難降的妖魔是什么腹殿? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,168評(píng)論 1 278
  • 正文 為了忘掉前任独悴,我火速辦了婚禮,結(jié)果婚禮上锣尉,老公的妹妹穿的比我還像新娘刻炒。我一直安慰自己,他們只是感情好自沧,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,153評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布坟奥。 她就那樣靜靜地躺著,像睡著了一般拇厢。 火紅的嫁衣襯著肌膚如雪爱谁。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 48,954評(píng)論 1 283
  • 那天孝偎,我揣著相機(jī)與錄音访敌,去河邊找鬼。 笑死衣盾,一個(gè)胖子當(dāng)著我的面吹牛寺旺,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播势决,決...
    沈念sama閱讀 38,271評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼迅涮,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了徽龟?” 一聲冷哼從身側(cè)響起叮姑,我...
    開(kāi)封第一講書(shū)人閱讀 36,916評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎据悔,沒(méi)想到半個(gè)月后传透,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,382評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡极颓,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,877評(píng)論 2 323
  • 正文 我和宋清朗相戀三年朱盐,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片菠隆。...
    茶點(diǎn)故事閱讀 37,989評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡兵琳,死狀恐怖狂秘,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情躯肌,我是刑警寧澤者春,帶...
    沈念sama閱讀 33,624評(píng)論 4 322
  • 正文 年R本政府宣布,位于F島的核電站清女,受9級(jí)特大地震影響钱烟,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜嫡丙,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,209評(píng)論 3 307
  • 文/蒙蒙 一拴袭、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧曙博,春花似錦拥刻、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,199評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至尘吗,卻和暖如春逝她,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背睬捶。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,418評(píng)論 1 260
  • 我被黑心中介騙來(lái)泰國(guó)打工黔宛, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人擒贸。 一個(gè)月前我還...
    沈念sama閱讀 45,401評(píng)論 2 352
  • 正文 我出身青樓臀晃,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親介劫。 傳聞我的和親對(duì)象是個(gè)殘疾皇子徽惋,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,700評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容