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的异同
)相同点
都可以作为方法的返回类型
)不同点
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以后,认为是动态类型,不在检测类型
动态绑定
)在objective-c 中,一个对象内是否调用指定的方法不是由编译器决定而是由运行时决定,这被称作是方法的动态绑定。
)在objective-c里,对象不调用方法,而是接收消息,消息 表达式:[reciver message];运行时系统首先确定接收者的类型(动态类型识别),然后根据消息名在类的方法列表里选择相依的方法执行,所以在源代码里消息也称为选择器(selector)
)消息函数的作用:
首先通过第一个参数的receiver,找到它的isa指针,然后在isa指向的Class对象中使用第二个参数selector查找方法
如果没有找到,就使用当前Class对象中的新的isa指针到上一级的父类的Class 对象中查找
当找到方法后,再依据receiver的中的self 指针找到当前的对象,调用当前对象的具体实现的方法(IMP),然后传递参数,调用实现方法
假如一致找到NSObject的Class对象,也没有找到你调用的方法,就会报告不能识别发送信息的错误
动态类型检测方法
对象再运行时获取其类型的能力称为内省,内省可以有多种方法实现
)判断类型
-(BOOL)isKindOfClass:clasObj 判断实例对象是否是这个类或者这个类的子类的实例
格式 :
对象 isKindOfClass:类对象 例:
Animal *ani= [Animal new];
BOOL isInstance=[ani isKindOfClass: [Animal class]]; )
-(BOOL)isMemberOfClass:classObj 判断是这个类的实例,不包括子类对象 格式:
对象 isMemberofClass:类对象
例如:
BOOL isINstance=[dog isMemberofClass:Animal class]];//NO =0 ; )
-(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 =@selector(eat:);
[ani performSelector:s2 withObject:@""] [ani performSelector:@selector(eat: andFoodName:)withObject:@"班长养得饿狗" withObject:@""]
OC 动态类型和静态类型的更多相关文章
- O-C相关-08-动态类型与静态类型
08-动态类型与静态类型 1, 什么是动态类型和静态类型 1) 动态语言 又叫动态编程语言,是指程序在运行时可以改变其结构:新的函数可以被引进,已有的函数可以被删除等在结构上的变化.比如众所周知的EC ...
- 【C#基础概念】编程语言:弱类型、强类型、动态类型、静态类型
一.看图区别编程语言 一般来讲,看第一个图就够了 这图是引用的,有错误,Python是强类型,但是图片中却归为弱类型了. 业界堆静态和动态的区分达到共识. 但是堆强类型和弱类型语言还未达成共识.我个人 ...
- mypy 支持静态类型编程的python变种
每种编程语言都有一群固定的用户,对于那些习惯将不同编程语言用成同样的感觉的人来说,最是难受.因为每种语言都有它独特的设计『哲学』和擅长的应用领域. PHP给大家的一贯的印象都是动态弱类型语言,Pyth ...
- Java——静态类型 实际类型
public class test { static class father { void run() { System.out.println("father run"); } ...
- go静态类型
go静态类型 静态类型语言意味着变量必须指定一个类型,例如整型.字符串.布尔型和数组等.可以在声明变量时指定变量类型.大多数情况下,让编译器自动去推断变量类型(我们将看到一些简单的例子). 关于静态类 ...
- 类型检查和鸭子类型 Duck typing in computer programming is an application of the duck test 鸭子测试 鸭子类型 指示编译器将类的类型检查安排在运行时而不是编译时 type checking can be specified to occur at run time rather than compile time.
Go所提供的面向对象功能十分简洁,但却兼具了类型检查和鸭子类型两者的有点,这是何等优秀的设计啊! Duck typing in computer programming is an applicati ...
- C语言,C#,Java,JavaScript之强类型与弱类型
奇葩的我今天想到一个坑爹的问题,都说Java是强类型的语言,JavaScript是弱类型的语言. 嗯嗯,那初学时候的C语言呢? 呵呵哒,突然觉得短路了.说Java是强类型的语言是因为遇到这样的情况: ...
- OC 动态类型,动态绑定,动态加载
OC 动态类型,动态绑定,动态加载 Objective-C具有相当多的动态特性,基本的,也是经常被提到和用到的有 动态类型(Dynamic typing) 动态绑定(Dynamic binding) ...
- 是否含有RTTI(运行时类型信息)是动态语言与静态语言的主要区别
运行时类型信息代表类型信息和对内存的操作能力. 运行时类型信息是运行时系统的基础. 类型信息分为编译时类型信息和运行时类型信息两种: 静态语言的类型信息只在编译时使用和保留,在可执行文件中没有类型信息 ...
随机推荐
- pcntl_fork 导致 MySQL server has gone away 解决方案
pcntl_fork 前连数据库,就会报 MySQL server has gone away 错误.原因是子进程会继承主进程的数据库连接,当mysql返回数据时,这些子进程都可以通过这个连接读到数据 ...
- Linux shell-tail
使用tail --help查看命令用于备忘 tail [ -f ] [ -c Number | -n Number | -m Number | -b Number | -k Number ...
- 利用shell批量改名和linux中取随机数的方法
先批量创建文件 #!/bin/sh if [ ! -d /tmp/chenyao ] then mkdir /tmp/chenyao -p fi cd /tmp/chenyao ..} do touc ...
- 搭建 redis 3.2.8服务器
实验环境 redis 3.2.8 + RHEL 7.3 系统 软件下载地址 http://download.redis.io/releases/redis-3.2.8.tar.gz #注意,我的软件包 ...
- 老李秘技:LoadRunner支持参数文件极限是多大
老李秘技:LoadRunner支持参数文件极限是多大 Controller不支持参数文件大于20m
- EDP转接IC NCS8805:RGB/LVDS转EDP芯片,带Scaler
RGB/LVDS-to-eDP Converter w/ Scaler1 FeaturesEmbedded-DisplayPort (eDP) Output1/2/4-lane eDP @ 1.62/ ...
- 关于laravel框架的跨域请求/jsonp请求的理解
最近刚接触laravel框架,首先要写一个跨域的单点登录.被跨域的问题卡了两三天,主要是因为对跨域这快不了解,就在刚才有点茅塞顿开的感觉,我做一下大概整理,主要给一些刚接触摸不着头脑的看,哪里写得不对 ...
- Windows入门基础:2.vs2013中Icon显示
第一:系统小图标的显示 wndclass.hIcon = LoadIcon(NULL,IDI_WARNING); //LoadIcon函数的第一的参数要为0,第二个参数是系统自定义的ID号: IDI_ ...
- 1129: 零起点学算法36——3n+1问题
1129: 零起点学算法36--3n+1问题 Time Limit: 1 Sec Memory Limit: 64 MB 64bit IO Format: %lldSubmitted: 4541 ...
- Java原子变量
实现全局自增id最简单有效的方式是什么?java.util.concurrent.atomic包定义了一些常见类型的原子变量.这些原子变量为我们提供了一种操作单一变量无锁(lock-free)的线程安 ...