OC 动态类型和静态类型

多态

允许不同的类定义相同的方法

  

动态类型

程序直到执行时才能确定所属的类

  

静态类型

将一个变量定义为特定类的对象时,使用的是静态形态

  

    将一个变量定义为特定类的对象时,使用的是静态类型,在编译的时候就知道这个变量所属的类,这个变量总是存储特定类的对象。使用静态类型时,编译器尽可能的确保变量的用法在程序中始终保持一致,编译器能够通过检查来确定应用于对象的方法是由该类定义的或者由该类继承的,否则就会显示警告,静态类型能够更好地在程序编译阶段就指出错误.并且使用静态类型可以提高程序的可读性

  

简单来说:
    Person  *p =[Person new];
    编译器判断左右两边类型一致时,就是静态类型
    Person *p =[Man new];
    编译器判断左右两边类型不一致时,就当做动态类型进行处理,随后会判断左右两边是否有类的关联关系

  

为什么要有动态类型?

多态的出现是为了让不同的类能使用同名的方法,这会让程序的可读性大大提高,也降低了编程难度

编译时和运行时检查

因为存储在id变量中的对象类型在编译的时候是无法确定的,所以一些事情是需要在运行时才能够确定例如:类Dog只有一个run方法 ,而类Cat只有一个jump方法,那么下面这段代码在编译的时候就会出错Dog *dog =[[Dog alloc]init];[dog jump];

因为编译器知道dog是Dog类的一个对象,而当遇到[dog jump]消息的时候,编译器同样知道Dog类是没有jump方法的,所以在编译器阶段就会提出警告,但是如果将代码换成下面的样子,在编译阶段就不会出错

Animal *car =[[Dog alloc]init];[(Cat *) cat jump];

因为在编译阶段编译器并不知道cat中存放的对象的类型是什么,所以在运行的时候程序就会crash

  

id类型及应用场景

用NSObject访问子类对象方法
    //定义id类型
    NSObject *obj =cat;
    [(Cat*) obj run];

 

id类型

id是一种通用的对象类型,它可以用来存储属于任何类的对象也可以理解为"万能指针"

注意:在id的定义中,已经包好了 *号.id指针只能指向os的对象

  

id类型的定义

typedef struct objc object{

      Class isa;

}*;
局限性:调用一个不存在的方法,编译器会马上报错

IOS5之后推出了 instancetype类型

instancetype和id的异同
1)相同点
    都可以作为方法的返回类型
2)不同点
    instancetype可以返回和方法所在类相同类型的对象,id只能返回未知类型的对象;
    instancetype只能作为返回值,不能像id那样作为参数

  

id类型的应用场景

//动物类
Animal *animal =[Animal new];
//狗的类,狗继承自动物
Dog *dog=[Dog new];
//猫的类,猫继承自动物
Cat *cat =[Cat new];
//定义id类型
id obj = cat ;//id obj = dog;
[obj run];

//NSObject 和id 都可以指向任何对象//NSObject 对象进行编译时检查(需要强制类型转换)//id不需要强制类型转换,id可以直接用//编译器看到id以后,认为是动态类型,不在检测类型

  

动态绑定

1)在objective-c 中,一个对象内是否调用指定的方法不是由编译器决定而是由运行时决定,这被称作是方法的动态绑定。
2)在objective-c里,对象不调用方法,而是接收消息,消息 表达式:[reciver message];运行时系统首先确定接收者的类型(动态类型识别),然后根据消息名在类的方法列表里选择相依的方法执行,所以在源代码里消息也称为选择器(selector)
3)消息函数的作用:
    首先通过第一个参数的receiver,找到它的isa指针,然后在isa指向的Class对象中使用第二个参数selector查找方法
    如果没有找到,就使用当前Class对象中的新的isa指针到上一级的父类的Class 对象中查找
    当找到方法后,再依据receiver的中的self 指针找到当前的对象,调用当前对象的具体实现的方法(IMP),然后传递参数,调用实现方法
    假如一致找到NSObject的Class对象,也没有找到你调用的方法,就会报告不能识别发送信息的错误

  

动态类型检测方法

对象再运行时获取其类型的能力称为内省,内省可以有多种方法实现
1)判断类型
-(BOOL)isKindOfClass:clasObj 判断实例对象是否是这个类或者这个类的子类的实例
    格式 :
        对象 isKindOfClass:类对象

     例:
        Animal *ani= [Animal new];
        BOOL isInstance=[ani isKindOfClass: [Animal class]];

2) -(BOOL)isMemberOfClass:classObj 判断是这个类的实例,不包括子类对象

  格式:     对象 isMemberofClass:类对象  例如:    BOOL isINstance=[dog isMemberofClass:Animal class]];//NO =0 ;

3)  -(BOOL)isSubclassOfClass:classObj 判断类是否是指定类的子类

  

判断实例对象能否相应指定的方法

判断实例是否有这样的方法
    -(BOOL) respondsToSelector:seletor

  例:    Animal *ani =[Animal new];    SEL s1 = @selector(eat);//把eat包装成SEL类型    BOOL isRespond=[ani respondsToSelector:(s1)]    

  

响应方法

应用selector指定的方法  -(id)performSelector:selector

  //动态类型检测:响应方法  Animal *ani =[Animal new];    if([ani respondsToSelector:@selector(eat)]){        }else{    NSLog(@"这个方法不能被响应");    }

  响应方法:    Animal *ani =[Animal new];

    SEL s1= @selector(eat);    if([ani respondsToSelector:s1]){      [ani performSelector:s1];//作用,响应方法    }else{

    }

   //多参数 performSelector:s2 withObject:
    SEL s2 [email protected](eat:);    [ani performSelector:s2 withObject:@""]

       [ani performSelector:@selector(eat: andFoodName:)withObject:@"班长养得饿狗" withObject:@""]

  

  

 

时间: 2024-10-14 10:37:19

OC 动态类型和静态类型的相关文章

O-C相关-08-动态类型与静态类型

08-动态类型与静态类型 1, 什么是动态类型和静态类型 1) 动态语言 又叫动态编程语言,是指程序在运行时可以改变其结构:新的函数可以被引进,已有的函数可以被删除等在结构上的变化.比如众所周知的ECMAScript(JavaScript)便是一个动态语言.除此之外如Ruby.Python等也都属于动态语言,而C.C++等语言则不属于动态语言. 而其实我们平时说的"动态语言"应该指的是"动态类型语言".至少我之前一直是这么认为的. 2) 动态类型语言 在运行时确定类

弱类型、强类型、动态类型、静态类型

装载: https://www.zhihu.com/question/19918532 弱类型: > "1"+2 '12' 强类型: >>> "1"+2 Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: cannot concatenate 'str' and 'int' objects

动态语言,静态类型,强类型定义语言,弱类型定义语言,

1 动态语言和静态语言 通常我们所说的动态语言.静态语言是指动态类型语言和静态类型语言.   1 动态类型语言:动态类型语言是指在运行期间才去做数据类型检查的语言,也就是说,在用动态类型的语言编程时,永远也不用给任何变量指定数据类型,该语言会在你第一次赋值给变量时,在内部将数据类型记录下来.Python和Ruby就是一种典型的动态类型语言,其他的各种脚本语言如VBScript也多少属于动态类型语言. 2 静态类型语言:静态类型语言与动态类型语言刚好相反,它的数据类型是在编译其间检查的,也就是说在

强类型,弱类型,动态类型,静态类型

"C and C++ are considered weakly typed since, due to type-casting, one can interpret a field of a structure that was an integer as a pointer." 我当前使用的开发语言为C/C++,为弱类型语言,主要因为: 1. 一些编程语言(例如C/C++)将指针暴露为数字值,并允许用户对它们执行算术运算.这些语言有时被称为"弱类型",因为指针

动态语言和静态语言、编译型语言和解释型语言、强类型语言和弱类型语言的分析

一.动态语言和静态语言1. 我们常说的动.静态语言,通常是指: 动态类型语言 Dynamically Typed Language 静态类型语言 Statically Typed Language 可能还有:动.静态编程语言 Dynamic\Statically Programming Language 2.    动态类型语言:在运行期间检查数据的类型的语言例如:Ruby\Python这类语言编程,不会给变量指定类型,而是在附值时得到数据类型.Python是动态语言,变量只是对象的引用,变量a

C++ 对象的静态类型与动态类型

在C++当中:因为出现了继承: 继承导致对象的指针和引用具有两种不同的类型: 静态类型 和 动态类型 . 静态类型 :指针或者是引用声明时的类型. 动态类型 :由他实际指向的类型确定. class Base { } class Derived:public Base { } Base* base //base的静态类型是 Base* = new Derived;//base的动态类型是 Derived* Derived* derived //derived的静态类型是 Derived* = ne

什么是动态语言和静态语言?静态语言动态语言的区别

定义 通常我们所说的动态语言.静态语言指 动态类型语言(Dynamically Typed Language)和 静态类型语言Statically Typed Language).还有一个 Dynamic Programming Language (动态编程语言),静态编程语言. 动态类型语言:在运行期间检查数据的类型的语言.用这类语言编程,不会给变量指定类型,而是在附值时得到数据类型.如:Python和ruby就是典型动 态类型语言.很多脚本语言vbscrīpt,javascrīpt也是这类语

【OC学习-16】动态VS静态类型识别?什么是动态绑定和动态加载?

动态VS静态 我们在实例化一个对象时,一般都是如下,就是静态类型: ASPerson * person=[[ASPerson alloc]init]; 还有一种是动态类型: id person=[[ASPerson alloc]init]; 可以看出来: (1)一般的带有明显类名(静态指针)的都是静态类型,而用id的通用指针的都是动态类型: (2)静态类型更容易阅读,更友好: (3)一般不涉及多态的时候,尽量用静态类型. 动态绑定和动态加载 这其实是针对类和对象说得,就是很多事情都不是事先弄好的

OC 动态类型,动态绑定,动态加载

Objective-C具有相当多的动态特性,基本的,也是经常被提到和用到的有 动态类型(Dynamic typing) 动态绑定(Dynamic binding) 动态加载(Dynamic loading) 动态类型:程序直到执行时才能确定所属的类. id 数据类型id 通用的对象类型,可以存储任意类型的对象,id后面没有号,它本身就是个指针类似于void ,但只可以指向对象类型 静态类型与动态类型 编译期检查与运行时检查 静态类型在编译期就能检查出错误 静态类型声明代码可读性好 动态类型只有在