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(运行时类型信息)是动态语言与静态语言的主要区别
运行时类型信息代表类型信息和对内存的操作能力. 运行时类型信息是运行时系统的基础. 类型信息分为编译时类型信息和运行时类型信息两种: 静态语言的类型信息只在编译时使用和保留,在可执行文件中没有类型信息 ...
随机推荐
- JS中有关对象的继承以及实例化、浅拷贝深拷贝的奥秘
一.属性的归属问题 JS对象中定义的属性和方法如果不是挂在原型链上的方法和属性(直接通过如类似x的方式进行定义)都只是在该对象上,对原型链上的没有影响.对于所有实例共用的方法可直接定义在原型链上这样实 ...
- 【转】JavaScript中使用ActiveXObject操作本地文件夹的方法
原文链接:http://www.jb51.net/article/48538.htm
- Android内存优化之OOM
内容大多都是和OOM有关的实践总结概要.理解错误或是偏差的地方,还请多包涵指正,谢谢!本人Q:1524447071 (一)Android的内存管理机制 Google在Android的官网上有这样一篇文 ...
- Struts2基础学习(五)—拦截器
一.概述 1.初识拦截器 Interceptor 拦截器类似前面学过的过滤器,是可以在action执行前后执行的代码,是我们做Web开发经常用到的技术.比如:权限控制.日志等.我们也可以将多 ...
- BZOJ1857 传送带 (三分法求单峰函数极值)
第一次发BZOJ的题解,先从水题开始吧,好不容易找到一道水题,那就从这题开始吧. 1.题设部分{ 题目描述: 在一个2维平面上有两条传送带,每一条传送带可以看成是一条线段.两条传送带分别为线段AB和线 ...
- char , unsigned char 和 signed char 区别
ANSI C 提供了3种字符类型,分别是char.signed char.unsigned char.char相当于signed char或者unsigned char,但是这取决于编译器!这三种字符 ...
- kafka各个版本特性预览介绍
kafka-0.8.2 新特性 producer不再区分同步(sync)和异步方式(async),所有的请求以异步方式发送,这样提升了客户端效率.producer请求会返回一个应答对象,包括偏移量或者 ...
- 第十章 MyBatis入门
第十章 MyBatis入门10.1 MyBatis入门 优点:简单且功能强大.能够完全控制SQL语句.容易维护和修改 缺点:移植性不好 使用步骤: 1.下载 ...
- cookie和session的区别异同
1.用于保存页面信息:如自动登录,记住用户名 2.对于同一个网站只有一套cookie,它是以域名为单位的,一个域名就是一套,数量大小有限4k-10k,同时会具有过期时间 3.JS中通过document ...
- 【外文翻译】 为什么我要写 getters 和setters
原文作者: Shamik Mitra 原文链接:https://dzone.com/articles/why-should-i-write-getters-and-setters 当我开始我的java ...