/**
1.定義一個類層次作爲例子
2.檢查類型
3.向下轉型(Downcasting)
4.Any和AnyObject的類型檢查
類型檢查是一種檢查類實例的方式,並且或者也是讓實例作爲它的父類或者子類的一種方式
類型檢查在swift中使用is和as操作符實現,這連個操作符提供了一種簡單達意的方式去檢查值的類型或者轉換它的類型
也可以用來檢查一類是夠實現了,某個協議
*/
class MediaItem {
var name: String;
init(name: String) {
self.name = name;
}
}
class Movie: MediaItem {
var director: String;
init(name: String, director: String) {
self.director = director;
super.init(name: name);
}
}
class Song: MediaItem {
var artist: String;
init(name: String, artist: String) {
self.artist = artist;
super.init(name: name);
}
}
let library = [
Movie(name: "萬萬沒想到", director: "叫獸易小星"),
Movie(name: "屌絲男士", director: "大鵬"),
Song(name: "一次就好", artist: "楊宗緯"),
Song(name: "如果沒有如果", artist: "林俊杰")
];
//檢查類型
/**
用類型檢查操作符 is 來檢查一個實例是否屬於特定子類型。若實例屬於那個子類型,類型檢查操作符返回true,若不屬於返回false
*/
var movieCount = 0;
var songCount = 0;
//var mediaCount = 0;
for item in library {
if item is Movie {
movieCount++;
}else if item is Song {
songCount++;
}
// if item is MediaItem {
// mediaCount++;
// }
}
print("movieCount is \(movieCount)\nsongCount is \(songCount)");
//向下轉型
/**
某類型的一個常量或變量可能在幕後實際上屬於一個子類,嘗試向下轉到它的子類型,用類型檢查操作符(as)
因爲向下轉型可能會失敗,類型檢查操作符帶有兩種不同形式。可選形式as?返回一個你試圖下轉成功的類型的可選值。強制形式as把試圖向下轉型和強制解包結果作爲一個混合動作
詳見資料
let movie = item as? Movie 嘗試將item轉爲Movie類型,若成功,設置一個新的臨時常量movie來存儲返回的可選Movie
轉換沒有真的改變實例或它的值,潛在的根本的實例保持不變,只是簡單地把它作爲它被轉換成的類來使用
*/
for item in library {
if let movie = item as? Movie {
print("Movie: '\(movie.name)', dir. \(movie.director)");
}else if let song = item as? Song {
print("Song: '\(song.name)', by \(song.artist)");
}
}
//Any和AnyObject的類型檢查
let someObject: [AnyObject] = [
Movie(name: "港囧", director: "徐崢"),
Movie(name: "老炮", director: "管虎"),
Movie(name: "煎餅俠", director: "大鵬")
];
for object in someObject {
let movie = object as! Movie;
print("Movie: '\(movie.name)', dir. \(movie.director)");
// if let movie = object as? Movie{
// print("Movie: '\(movie.name)', dir. \(movie.director)");
// }
}
//爲了變爲一個更短的形式,下轉someObjects數組爲Movie[]類型來代替下轉每一項方式
for movie in someObject as! [Movie] {
print("Movie: '\(movie.name)', dir. \(movie.director)");
}
//Any類型
var things = [Any]();
things.append(0);
things.append(0.0);
things.append(42);
things.append(3.14159);
things.append("hello");
things.append((3.0, 5.0));
things.append(Movie(name:"sfs", director: "gerg"));
for thing in things {
switch thing {
case 0 as Int:
print("zero as an Int");
case 0 as Double:
print("zero as an Double");
case let someInt as Int:
print("an integer value of \(someInt)");
case let someDouble as Double where someDouble > 0:
print("a positive double value of \(someDouble)");
case is Double:
print("some other double value that I don't want to print");
case let someString as String:
print("a string value of \"\(someString)\"");
case let (x, y) as (Double,Double):
print("an (x, y) point at \(x), \(y)");
case let movie as Movie:
print("a movie called '\(movie.name)', dir.\(movie.director)");
default:
print("something else");
}
}
/**
在一個switch語句的case中使用強制形式的類型檢查操作符(as,而不是as?)來檢查和轉換到一個明確的類型。在switch case語句的內容中這種檢查總是安全的
*/