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)
}
}