import Foundation
//***********************************************************************************************
//1.Type Casting(类型转换)
//_______________________________________________________________________________________________
//介绍
//类型转化是一种检查实例的方式,类型转化在 Swift 中 使用 is 和 as 操作符来实现,这两个操作符提供了一种简单的表达意思的方式去检查值的类型或者转换值的类型
//2.Defining a Class Hierarchy for Type Casting(定义一个类层次作为例子)
//我们用它在类和子类的层次结构上,检查特定类的实例的类型并且转换这个类实例的类型成为这个层次结构中的其他类型
//_______________________________________________________________________________________________
//实例代码演示类层次的类型转化
class MediaItem{ //定义媒体基础父类
var name: String
init(name: String) {
self.name = name
}
}
class Movie: MediaItem{ //定义电影子类
init(name: String,director: String){
self.director = director
super.init(name: name)
}
}
class Song: MediaItem{ //定义音乐子类
init(name: String,artist: String){
self.artist = artist
super.init(name: name)
}
}
let library = [ //创建数组存储类实例,在幕后 library 里存储的项依然是 Movie 和 Song 类型的,但是,若你迭代它,Swift 会自动识别 Movie 类和 Song 类有共同的父类 MediaItem类,所以取出的实例会是 MediaItem 类型的,而不是 Movie 和 Song 类型的。为了让它们作为它们本来的 类型工作,你需要检查它们的类型或者向下转换它们的类型到其它类型
Movie(name: "Casablanca",director: "Michael Curtiz "),
Song(name: " BlueSuede Shoes",artist: "Elvis Presley"),27)"> Movie(name: "Citizen Kane",director : "Orson Welles "),27)"> Song(name: "The One And Only",artist: "Chesney Hawkes"),27)"> Song(name: " Never Gonna Give You Up",artist: "Rick Astley")
]
//3.Checking Type(检查类型)
//实例代码演示检查类型(用类型检查操作符(is)来检查一个实例是否属于特定子类型。类型检查操作符返回 true 若 实例属于那个子类型,若不属于返回 false)
var movieCount = 0
var songCount = 0
for item in library{
if item is Movie{ //使用 is 来检查类型
++movieCount
}
else if item is Song{
++songCount
}
}
println("Media library contains \(movieCount) movies and \(songCount) songs")
//4.Downcasting(向下转型(简称下转))
//某类型的一个常量或变量可能在幕后实际上属于一个子类。你可以相信,上面就是这种情况。你可以尝试向下转到它的子类型,用类型转换操作符(as)
//如果不确定下转一定成功,使用 as 的可选类型 as?
//实例代码演示下转类型
for item in library{
if let movie = item as? Movie{ //试图用 as? 来将 item 由 MediaItem 类下转为 Movie 类,他可能为 Movie 类,也可能为 Song 类,或者仅仅为 MediaItem 类的实例,因为不确定,使用 as? 来试图下转返回一个可选值 Movie?
println("Movie: '\(movie.name)',dir.\(movie.director)")
}
else if let song = item as? Song{
println("Song: '\(song.name)',by \(song.artist)")
}
}
//5.Type Casting for Any and AnyObject(Any 和 AnyObject 的转换)
//Swift 为不确定类型提供了两种特殊类型别名:1.AnyObject 可以代表任何 class 类型实例;2.Any 可以表示任何类型,包括非 class 类型,除了方法类型
//AnyObject类型代码演示
let someObjects: [AnyObject] = [ //定义 AnyObject 类型的数组并且包含三个元素(只能为 class 类型的元素)
Movie(name: "2001: A Space Odyssey",director: "Stanley Kubrick"),
Movie(name: "Moon",director: "Duncan Jones"),
Movie(name: "Alien",director: "Ridley Scott")
]
for object in someObjects{
let movie = object as Movie
println("Movie: '\(movie.name)',dir.\(movie.director)")
}
//Any 类型代码演示
var things = [Any]() //创建混合类型数据一起工作的数组 things,包含非 class 类型
things.append(0)
things.append(0.0)
things.append(42)
things.append(3.14159)
things.append("hello")
things.append(Movie(name: "Ghostvusters",director: "Ivan Reitman"))
for thing in things{ //使用 switch 来灵活应用 is 和 as
switch thing{
case 0 as Int:
println("zero as an Int")
case 0.0 as Double:
println("zero as a Double")
case let someInt as Int:
println("an integer value of \(someInt)")
case let someDouble as Double where someDouble > 0:
println("a positive double value of \(someDouble)")
case is Double:
println("some other double value that I don't want to print")
case let someString as String:
println("a string value of \"\(someString)\"")
case let (x,y) as (Double,Double):
println("an (x,y) point at \(x),\(y)")
case let movie as Movie:
println("a movie called '\(movie.name)',dir. \(movie.director )")
default:
println("something else")
}
}