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(运行时类型信息)是动态语言与静态语言的主要区别
运行时类型信息代表类型信息和对内存的操作能力. 运行时类型信息是运行时系统的基础. 类型信息分为编译时类型信息和运行时类型信息两种: 静态语言的类型信息只在编译时使用和保留,在可执行文件中没有类型信息 ...
随机推荐
- 简单的android启动跳转页面
java代码示例: package com.rcl; import android.app.Activity;import android.content.Intent;import android. ...
- python生成二维码
1.python-qrcode是个用来生成二维码图片的第三方模块,依赖于 PIL 模块和 qrcode 库. 首先,我们要安装三个模块,qrcode,image,PIL. pip install q ...
- Liniux系统下目录的权限意义
访问者及其基本权限 Linux系统内的文件访问者有三种身份,分别是: a) 文件和文件目录的所有者: u---User(所有权);b) 文件和文件目录的所有者所在的组的用户: g---Group;c) ...
- 学习smart gwt 的一些好的网站
最近在学smart gwt,这个框架和我们比较熟悉的SSH实现思路上有点不一样,因为技术是外国的,所以好多东西都是英文的,正因为是英文的,我们学到的东西才是最多最好的,好了,网站如下: gwt api ...
- 手机自动化测试:appium源码分析之bootstrap一
手机自动化测试:appium源码分析之bootstrap一 前言: poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.popte ...
- CSS3选择器~一看吓一跳,这么多不会
复习CSS时发现很多选择器不会,因为平时很少用到.现在干脆一不做二不修,全部温习一遍.本文参考http://css.doyoe.com/. 一.元素选择器 图片来自:http://css.doyoe. ...
- Python可视化学习(2):Matplotlib快速绘图基础
Matplotlib将大部分的绘图对象都封装成为对象,故理论上所有的图表元素(如Line2D, Text,Label等)都是对象,都可以将其在图表中提取出来并配置实例的属性.同时,Matplotlib ...
- TableView cell自适应高度-----xib
1.通过xib创建一个cell,将label进行上左下右,进行适配, self.automaticallyAdjustsScrollViewInsets = NO; self.edgesForExte ...
- 第一个SignalR案例
说明:开发的案例为Hub(集线器) 一.开发环境 VS2013 ,window10 二.步骤 打开vs创建一个新的解决方案,添加一个空的WebForm项目. 使用NuGet添加引用.命令:PM> ...
- ValueStack
1.把list集合压入栈顶 /** * * 查找所有的用户 * @return */ public String findAll() { List<User> allUser = user ...