7、面向對象數據庫
swift能夠定義編程
面向對象類型: 枚舉 結構體 類 ,能夠定義變量,枚舉,結構體是值類型,類定義變量是引用類型swift
以上三種都支持定義存儲屬性,計算屬性,方法,下標,構造器,嵌套類型。數組
JAVA支持的特性,swift都支持,不支持的,它也支持,語法簡潔,但功能並不簡單,反而很強大!app
OOP :Object Oriented Programming 以對象爲中心編程函數
對象總有狀態和行爲,對應的:性能
屬性:描述對象的狀態測試
方法:描述對象的行爲ui
面向對象兩大核心:類和對象spa
類:具備共同特徵的對象的定義,如 人類, 對象是類的具體實例,你,我,喬布斯,雷蛋蛋
面向對象典型三大特徵:
封裝: 把對象的狀態數據,實現細節隱藏起來,只露出合適的方法,容許外部程序調用,改變程序狀態。 private ,internal public 限制封裝
繼承:複用已有的類,通常到特殊,蘋果繼承了水果,單繼承,經過協議來彌補不足
多態:
swift 的 類 結構體 枚舉 具備徹底平等的地位
5種面向對象程序單元爲:類,結構體,枚舉,擴展,協議
注意:實例和對象不一樣
實例:結構體和枚舉的實例
對象:類的實例
複雜的是:swift 中 類,結構體,枚舉的內部分別能夠定義屬性(存儲屬性和計算屬性),方法,下標,構造器,嵌套類型(嵌套類,嵌套結構體,嵌套枚舉) 這5種類型成員!
真是讓人 要瘋了~
只有類支持繼承
人之爲學有難易乎?爲之,則難者亦易矣,不爲,則易者亦難矣!
枚舉:管理一組有限的值的集合 enum 名字首字母大寫,連續駝峯命名法
好比季節 性別
不一樣的是:成員不會默認分配一個整數值
enum Weekday
{
case Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday
}
調用
var chooseDay = Weekday.Saturday
switch(chooseDay)
{
case .Monday:
println("星期一")
case .Tuesday:
。。。相似 省略
}
原始值:可使 Int ,Double,Float,Character,String 類型的值
enum Weekday :Int
{
case Monday,Tuesday = 1,Wednesday=5,Thursday,Friday,Saturday,Sunday
}
enum Season :Character
{
case Spring = "S"
。。。
}
屬性:rawValue 獲取指定枚舉值的原始值
var day = Weekday.Saturday
day.rawValue //8
關聯值:associated value
相似屬性,爲每一個枚舉值定義更多的數據,從而更好地描述該枚舉表明的實例的狀態。
enum Planet
{
case Mercury(weight:Doubel,density:Double,name:String)
case Earth(Double,String)
}
調用
var p1 = Planet.Mercury(weight:0.05,density:5.43,name:"水星")
類 官方說,主要是使用類
private internal public final
類定義,最經常使用的 構造器,屬性,方法
構造器:構造該類的實例
屬性:定義該類或該類的實例所包含的狀態數據
方法:定義該類或該類的實例的行爲特徵或者功能實現
類名後邊()表示調用 構造器,從而返回該類的實例
計算屬性:實例變量
存儲屬性:保存類型自己或實例的狀態數據
構造器 init 不能聲明返回值類型 無需寫return
class Person
{
//定義存儲屬性
var name:String = ""
var age:Int = 0
//定義方法
func say(content:String)
{
println(content)
}
}
// 建立實例
var p:Person
// 調用構造器
p = Person()
//上邊兩句 簡寫 成
var p = Person()
// 實例的做用
一、訪問實例屬性
二、調用實例的方法
p.name = "renhairui"
p.say("swift是一門很是強大的語言")
大多數狀況,定義一個類,就是爲了重複建立類的實例,類是多個實例的共同特徵
假如用上邊的例子建立 結構體
struct Person
{
//定義存儲屬性
var name:String
var age:Int
//定義方法
func say(content:String)
{
println(content)
}
}
則
var my = Person(name:"renhairui",age:28)
println(my.name) // renhairui
假如調用無參數的構造器建立實例
var hello = Person()
則 hello.age 是0
引用類型比較 === !==
比較兩個引用類型的變量是否指向同一個實例
只有引用類型的變量才能用 這個!
self關鍵字 指向該方法的調用者
實例方法中:self表明 調用該方法的實例
類型方法中:self表明代用該方法的類型(類或者結構體)
class Dog
{
func jump()
{
}
func run()
{
self.jump() //容許實例的成員調用另外一個成員,能夠省略self jump()正確!
}
}
在方法中強制引用存儲屬性 用self
class wolf
{
var name :String = ""
var age:Int = 2
init (name:String,age:Int)
{
self.name = name
self.age = age
}
func info ()
{
println("個人名字是\(name),年齡是\(age)歲")
}
}
調用
var wolf = Wolf(name:"任海瑞",age:28)
wolf.info()
self 做爲方法調用者時,能夠訪問self,甚至當成返回值
class ReturnSelf
{
var age:Int = 0
func grow()->ReturnSelf
{
age ++
return self
}
}
調用
var rt = ReturnSelf()
rt.grow()
.grow()
println(rt.age)
結構體:封裝少許相關的簡單數據值,該實例在賦值和傳遞時會自動複製副本
存儲屬性: 1定義是指定初始值,2構造器中定義初始值
延遲存儲 第一次被調用是纔會被計算初始值的屬性,lazy
lazy load 當某個實例持有另外一個建立成本比較大的實例的引用時,下降內存開銷,提高程序性能。
class Dept
{
var id:Int
var info:String
init (id:Int)
{
self.id = id
NSThread.sleepForTimeInterval(2)// 模擬耗時操做
self.info = "模擬讀取數據庫"
}
}
class User
{
var id:Int = 0
// 這個時候若是調用 Dept 則會建立較大成本實例 不能用 var dept = Dept(id :20)
lazy var dept = Dept(id:20)
var nicks = [String]()
}
//建立實例
var user =User()
user.nicks.append("孫悟空")
user.nicks.append("任海瑞")
println(user.nicks)
計算屬性:本質是 getter setter方法的組合
class User
{
var first:String = ""
var last:String = ""
var fullName:String
{
// 定義計算屬性的getter方法 返回值由first,last兩個存儲屬性決定
return first +"-"+last
}
set(newValue){
// 改變first last兩個存儲屬性
var names = newValue.componentsSeparatedBystring("-") //字符串切割成數組
self.first = names[0]
self.last = names[1]
}
}
init(first:String,last:String)
{
self.first =first
self.last = last
}
調用
let s = User(first:"海瑞",last:"任")
println(s.fullName) // 海瑞-任
s.fullName = "悟空-孫"
println(s.first) //悟空
println(s.last) //孫
setter方法提供隱式參數名 newValue 不用寫 直接用
set {
var names = newValue.componentsSeparatedBystring("-") //字符串切割成數組
self.first = names[0]
self.last = names[1]
}
不寫setter方法 就是只讀的計算屬性
屬性觀察者 willSet() didSet()
方法:行爲特徵的抽象
函數:放在枚舉,結構體,類之外定義
方法:上邊三種內定義,枚舉,結構體中用static,類中用class,意思同樣
類型.方法
實例.方法
class SomeClass
{
func test(){ //方法}
class func bar(#msg:String)
{
println("bar類型方法,傳入參數:\(msg)")
}
}
用
var sc = SomeClass()
//sc的test分離成函數 注意:千萬不能加(),不然變成方法調用,不是將方法賦值給函數類型的變量
var f1:()->() = sc.test
var f2:(String)->Void = SomeClass.bar
// 下面兩個同樣
sc.test() f1()
SomeClass.bar(msg:"測試信息") f2("測試信息")
注意:結構體,枚舉的實例方法不能分離,轉換成函數,他們的類型方法才能夠。
默認爲方法除第一個參數外的其餘形參都添加了外部形參名,不用寫外部參數名或者#了,比較人性化。
enum,stuct,class中的func是實例方法
命名習慣:
方法名,以動詞開頭,動詞+名詞(描述第一個參數的含義)
有時候還會在動詞和名詞之間 加 with,for ,by介詞,盡力把調用方法像一條簡單的英文句子
func indexOfObject()
可變方法
結構體和枚舉都是值類型,默認狀況下,實例方法不能改變實例的存儲屬性。
假如須要修改,則mutating 聲明爲可變方法,能夠在方法體內對隱式的self從新賦值
做用:改變枚舉,結構體的內部數據。
struct Rect
{
var x:Int
var y:Int
var width:Int
var height:Int
mutating func moveByx(x:Int,y:Int)
{
self.x += x
self.y += y
}
}
// 建立實例
var rect = Rect(x:20,y:12,width:200,height:300)
// 調用可變方法
rect.moveByx(100,y:80)
println("\(rect.x),\(rect.y)")
下標:能夠訪問 對象,結婚,序列(枚舉,結構體,類都支持)
P175