面向对象的特点
- 面向对象编程的三大特征:封装,继承,和多态
- Swift可以定义枚举,结构体,和类三种面向对象的类型
Class - 继承/引用类型
- 内存里的对象可以有多个引用,即多个引用变量指向同一个对象
- 如果一个引用更改了,那对象里的值也会更改。
- “===” 这个等号只能用于引用类型的比较,不能用于值类型的比较,所以不能用于枚举或者结构体
- “==” or “!=” ,这两个也可以用于比较引用类型,但是要用到运算符重载,详情见后期课程
格式
必须有init method
class Movie {
let title: String
let director: String
let releaseYear: Int
init(title: String, director: String, releaseYear: Int) {
self.title = title
self.director = director
self.releaseYear = releaseYear
}
}
Property
三类property: Stored property, Type properties, Computed property
默认是internal,就是可以app内访问
Stored property
大多数的stored property 是定义为常量,必须在init的时候被设定,external name 在init method中是必须的
var thursdayNightMovie = Movie(title:"Point Break", director:"Kathryn Bigelow", releaseYear: 1991)
Type properties & Computed Properties
class KidsMovie {
let title: String
let director: String
let releaseYear: Int
var mpaaRating: String
//Type property
static let permittedRatings = ["G", "PG"]
let reviewScores:[Double]
var metaScore: Double {
get {
let value = reviewScores.reduce(0) { $0 + $1 } / Double(reviewScores.count)
return value
}
}
init(title: String, director: String, releaseYear: Int, mpaaRating:String, reviewScores: [Double]) {
self.mpaaRating = mpaaRating
self.title = title
self.director = director
self.releaseYear = releaseYear
self.reviewScores = reviewScores
}
}
Calling Type methods
UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.PhotoLibrary)
使用class func ,子类可以重载,使用static则不会
class Hello {
let pipi:String
init (hello:String){
self.pipi = hello
}
//or class func .....
static func diao (hello:String){
print("why")
}
}
Enumeration - 不能继承/值类型
- 值对象是要复制的
- 每个值对象的更改,不会影响其他对象的更改
- 因此枚举和结构体是没有继承的
定义
Enum可以看做是一组有限的“抽象概念”的集合 (数组需要指定具体的数值类型)
enum PrimaryColor {
case Red
case Blue
case Yellow
}
可以用一个case,然后其他用逗号隔开
enum Aunties {
case Aime, Billie, Diane, Gail, Janie, Pam
}
enum中的元素可以设定任何类型原始值,如string,int
enum AmericanLeagueWest: String {
case As = "Oakland"
case Astros = "Houston"
case Angels = "Los Angeles"
case Mariners = "Seattle"
case Rangers = "Arlington"
}
var weather: AmericanLeagueWest
weather = AmericanLeagueWest.As
weather = .As //也可以这样写
使用rawValue提取成员的原始值
var message = "I hope the A's stay in \(AmericanLeagueWest.As.rawValue)"
Enums and switch
enum CaliforniaPark {
case Yosemite, DeathValley, Lasson, Sequoia
}
var warning = ""
var destination = CaliforniaPark.Yosemite
例子 1:switch中的case如果没有覆盖枚举的所有值,必须添加default语句
switch destination {
case .Yosemite:
warning = "Beware of aggressive bears!"
case .DeathValley:
warning = "Beware of dehydration!"
case .Lasson:
warning = "Watch out for boiling pools!"
case .Sequoia:
warning = "Watch out for falling trees!"
}
例子 2:
// Below is an enum and an if-else statement for implementing the game Rock-Paper-Scissors.
enum roshamboMove {
case Rock, Paper, Scissors
}
var myMove = roshamboMove.Scissors
var yourMove = roshamboMove.Scissors
var resultsMessage = ""
if myMove == .Rock && yourMove == .Paper || myMove == .Paper && yourMove == .Rock {
resultsMessage = "Paper covers Rock."
} else if myMove == yourMove {
resultsMessage = "It's a tie!"
} else if myMove == .Rock && yourMove == .Scissors || myMove == .Scissors && yourMove == .Rock {
resultsMessage = "Rock crushes Scissors. "
} else if myMove == .Paper && yourMove == .Scissors || myMove == .Scissors && yourMove == .Paper {
resultsMessage = "Scissors cut Paper."
}
// Solution
switch (myMove, yourMove) {
case (.Rock, .Paper), (.Paper, .Rock):
resultsMessage = "Paper covers Rock."
case (.Rock, .Rock), (.Paper, .Paper), (.Scissors, .Scissors):
resultsMessage = "It's a tie!"
case (.Rock, .Scissors), (.Scissors, .Rock):
resultsMessage = "Rock crushes Scissors."
case (.Paper, .Scissors), (.Scissors, .Paper):
resultsMessage = "Scissors cut Paper."
}
// Alternate solution
switch (myMove, yourMove) {
case (.Rock, .Paper), (.Paper, .Rock):
resultsMessage = "Paper covers Rock."
case let (a, b) where a==b :
resultsMessage = "It's a tie!"
case (.Rock, .Scissors), (.Scissors, .Rock):
resultsMessage = "Rock crushes Scissors."
case (.Paper, .Scissors), (.Scissors, .Paper):
resultsMessage = "Scissors cut Paper."
default:
resultsMessage = "Paper covers Rock."
}
例子3
var score = 97
var letterGrade = ""
// Solution
switch score {
case 90...100:
letterGrade = "A"
case 80...89:
letterGrade = "B"
case 70...79:
letterGrade = "C"
case 60...69:
letterGrade = "D"
default:
letterGrade = "Incomplete"
}
整型的枚举
//可以自动推断,不用每个都赋予原始值
enum Weekday: Int{
case Mon, Tur, Wen = 3, Thur, Fri, Sat , Sun
}
字符串枚举
//必须每个都赋予原始值,因为不能自动推断
enum Season3: Character{
case Spring = "春"
case Summer = "夏"
case Fall = "秋"
case Winter = "冬"
}
获取枚举值
var mySeason = Season3(rawValue:"春")
if mySeason != nil {
switch(mySeason!){ //不为空才能进行强制解析
case .Spring:
print("春天不是读书天")
case .Summer:
print("夏天炎炎正好眠")
case .Fall , .Winter:
print("秋多蚊蝇冬日冷")
default:
print("读书只好等明年")
}
}
关联值
enum Planet {
case Earth(weight: Double , name:String)
case Mars (density: Double, name: String, weight:Double)
case Venus(Double, String)
case Saturn
case Neptune
}
var p1 = Planet.Earth(weight:1.0, name:"地球")
var p2 = Planet.Venus(0.815,"金星")
var p3 = Planet.Mars(density:3.95, name:"火星",weight:0.1)
switch (p3){
//将关联值绑定到变量或者常量来提取
case Planet.Earth(var weight , var name):
print("此行星的名字为:\(name),质量相当于\(weight)个地球")
//将关联值都提取为常量或者变量,只将一个var或者let放在枚举成员之前
case let Planet.Mars(density:d, name:n, weight:w):
print("此行星的名字为:\(n),质量相当于\(w)个地球,密度为\(d)")
default:
break
}
Struct - 不能继承/值类型
struct PictureFrame {
var width = 5
var height = 7
var thickness: Double = 1.5
var area: Int {
get {
return (width * height)/2
}
}
}
Struct自动生成init method
var familyReunionFrame = PictureFrame(width: 10, height: 8, thickness: 1.5)
familyReunionFrame.area
enum, class, or struct?
只是单纯的存储数据,不需要继承
Struct Triangle {
let angles = [30, 60, 90]
let sides = [3,4,5]
}
存储“有限“的“成员”,不必考虑什么类型的数值
enum UIImagePickerControllerSourceType : Int {
case PhotoLibrary
case Camera
case SavedPhotosAlbum
}
只是单纯的存储数据,不需要继承
Struct Name {
var firstName: String
var lastName: String
}
存储“有限“的“成员”,不必考虑什么类型的数值
enum Subject {
case Math
case English
case Spanish
case Science
}
有各种类型的学生,大学,中学,意味着需要继承
class Student {
var grades = [97.0, 99.0, 98.0]
let name = Name(firstName:"Grace", lastName:"Hopper")
var favoriteSubject = Subject.Science
var gradePointAverage: Double {
get {
return (grades.reduce(0){$0 + $1})/Double (grades.count)
}
}
}