動態數據類型 (上)

id是一個數據類型, 并且是一個動態數據類型

既然是數據類型, 所以就可以用來

1.定義變量

2.作為函數的參數

3.作為函數的返回值

默認情況下所有的數據類型都是靜態數據類型

靜態數據類型的特點:

在編譯時就知道變量的類型,

知道變量中有哪些屬性和方法

在編譯的時候就可以訪問這些屬性和方法,

并且如果是通過靜態數據類型定義變量, 如果訪問了不屬于靜態數據類型的屬性和方法, 那么編譯器就會報錯

動態數據類型的特點:

在編譯的時候編譯器并不知道變量的真實類型, 只有在運行的時候才知道它的真實類型

并且如果通過動態數據類型定義變量, 如果訪問了不屬于動態數據類型的屬性和方法, 編譯器不會報錯

id == NSObject * 萬能指針

id和NSObject *的區別:

NSObject *是一個靜態數據類型

id ?是一個動態數據類型


Person *p = [Person new];

p.age = 30;

[p sleep];


Person *p = [Student new];

p.age = 30;

[p sleep];

// ? ?[p eat];

Student *stu = (Student *)p;

[stu eat];


NSObject *obj = [Person new];

[obj test];

NSObject *obj2 = [Student new];


// 通過靜態數據類型定義變量, 不能調用子類特有的方法

// 通過動態數據類型定義變量, 可以調用子類特有的方法

// 通過動態數據類型定義的變量, 可以調用私有方法

// 弊端: 由于動態數據類型可以調用任意方法, 所以有可能調用到不屬于自己的方法, 而編譯時又不會報錯, 所以可能導致運行時的錯誤

// 應用場景: 多態, 可以減少代碼量, 避免調用子類特有的方法需要強制類型轉換

id obj = [Person new];

[obj sleep];

[obj test];

[obj eat];

id obj2 = [Student new];

[obj2 eat];

[obj2 test];


// 為了避免動態數據類型引發的運行時的錯誤, 一般情況下如果使用動態數據類型定義一個變量, 在調用這個對象的方法之前會進行一次判斷, 判斷當前對象是否能夠調用這個方法

// ? ?id obj = [Person new];

id obj = [Student new];


if ([obj isKindOfClass:[Student class]]) {

// isKindOfClass , 判斷指定的對象是否是某一個類, 或者是某一個類的子類

[obj eat];

}


if ([obj isMemberOfClass:[Student class]]) {

// isMemberOfClass : 判斷指定的對象是否是當前指定的類的實例

[obj eat];

}

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容