IOS - 执行时 (多态)
一
多态概述
多态指同一操作作用于不同的对象。能够有不同的解释。产生不同的执行结果。它是面向对象程序设计(OOP)的一个重要特征,动态类型能使程序直到执行时才确定对象的所属类。其详细引用的对象在执行时才干确定。
动态绑定能使程序直到执行时才确定调用对象的实际方法。
C++使用虚函数(虚函数表)来实现动态绑定,当基类对象的指针(或引用)指向派生类的对象时候,实际调用的是派生类相应的函数。
是动态语言,所以它具有动态类型和动态绑定的特性。Objective-c系统总是跟踪对象所属的类。对于类型的推断和方法的确定都是在执行时进行。 那Objective-c是怎么样实现多态特性的呢?
@interface Draw : NSObject
@property (nonatomic,strong) NSString *name;
- (void) Print;
- (void) draw;
@end
@implementation Draw
@synthesize name;
- (id) init
{
[super init])
{
self.name = @"Draw Demo";
}
return self;
}
- (void) draw
{
NSLog(@"Draw::draw.......");
}
- (void) Print
{
NSLog(@"i am %@.",self.name);
}
@end
@end
@implementation Circle
- (void) draw
{
NSLog(@"%@:draw circle",self.name);
}
@end
@interface Retangle : Draw
@end
@implementation Retangle
- (void) draw
{
[super draw]; //通过superkeyword能够调用基类的draw函数
NSLog(@"%@:draw retangle",self.name);
}
@end
我们定义了一个Draw基类。里面有一个数据成员name,和两个函数成员draw和Print,Circle和Retangle是从Draw派生的两个类,他们重写了基类Draw的draw方法。
Draw* base = [[Circle alloc] init];
[base draw]; //draw circle
NSLog(@"address:%@",base);
base = [[Retangle alloc] init];
[base draw]; //draw retangle
NSLog(@"address:%@",base);
[base Print];
15:34:41.648 duotaidemo[7718:303] Draw Demo:draw circle
2014-04-09 15:34:41.673 duotaidemo[7718:303] address:<Circle: 0x1002027a0>
2014-04-09 15:34:41.674 duotaidemo[7718:303] Draw::draw.......
2014-04-09 15:34:41.674 duotaidemo[7718:303] Draw Demo:draw retangle
2014-04-09 15:34:41.675 duotaidemo[7718:303] address:<Retangle: 0x100205e70>
2014-04-09 15:34:41.676 duotaidemo[7718:303] i am Draw Demo.
因为Retangele没有重写基类的Print函数,全部使用[base
Print]调用的是基类的方法。
同一时候通过address的输出发现base指向了两个不同的对象。
id base = [[Circle alloc] init];
[base draw]; //draw circle
NSLog(@"address:%@",base);
base = [[Retangle alloc] init];
[base draw]; //draw retangle
NSLog(@"address:%@",base);
objc.h 文件里关于NSObject的定义
<NSObject>
Class isa OBJC_ISA_AVAILABILITY;
typedef struct objc_class *Class;
{
Class isa;
...);
详见:http://opensource.apple.com/source/objc4/objc4-493.9/runtime/objc.h
its isa instance variable, inherited from the NSObject class. isa identifies the object's class; it points to a structure that's compiled from the class definition. Through isa, an object can find whatever information it needs at run timesuch as its place
in the inheritance hierarchy, the size and structure of its instance variables, and the location of the method implementations it can perform in response to messages.
struct objc_class {
Class isa; /* metaclass */
Class super_class /* 父类的地址 */
const char *name /* 类名称 */
long version /* 版本号 */
long info /* 类信息 */
long instance_size /* 实例大小 */
struct objc_ivar_list *ivars /* 实例參数列表*/
struct objc_method_list **methodLists /* 方法列表 */
struct objc_cache *cache /* 方法缓存 */
struct objc_protocol_list *protocols /* protocol链表*/
类对象是一个依据类定义生成的一个结构体,里面存储了类的基本信息,
如:类的大小,类的名称,类的版本号以及消息与函数的映射表等信息。类对象所保存的信息在程序编译时确定,在程序启动 时载入到内存中。
在Objective-c中,id类型是一种通用的指针类型。id类型能够用来指向属于不论什么类的对象(仅仅要该对象是属于NSObject即成体系)。
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvemhhbmd6aGVianV0/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
= [[Circle alloc] init];
isa成员,訪问类对象所保持的类的信息,isa成员能够通过类对象获得当前实例能够訪问的消息列表。以及消息相应的函数地址。
IOS - 执行时 (多态)的更多相关文章
- iOS执行时工具-cycript
cycript是大神saurik开发的一个很强大的工具,能够让开发人员在命令行下和应用交互,在执行时查看和改动应用.它确实能够帮助你破解一些应用,但我认为这个工具主要还是用来学习其它应用的设计(主要是 ...
- IOS -执行时 (消息传递 )
一 函数调用概述 Objective-C不支持多重继承(同Java和Smalltalk),而C++语言支持多重继承. Objective-C是动态绑定,它的类库比C++要easy操作. Ob ...
- iOS开发时,在Xcode中添加多个Targets进行版本控制
在iOS开发中,很可能有以下场景:需要开发多个版本,或因需区分收费版,免费版,或因为网络环境需要区分测试版,发布版,或因渠道不同需要区分企业版,AppStore版等等.解决办法无非就是CheckOut ...
- 深入理解OOP(第一天):多态和继承(初期绑定和编译时多态)
在本系列中,我们以CodeProject上比较火的OOP系列博客为主,进行OOP深入浅出展现. 无论作为软件设计的高手.或者菜鸟,对于架构设计而言,均需要多次重构.取舍,以有利于整个软件项目的健康构建 ...
- 深入浅出OOP(三): 多态和继承(动态绑定/运行时多态)
在前面的文章中,我们介绍了编译期多态.params关键字.实例化.base关键字等.本节我们来关注另外一种多态:运行时多态, 运行时多态也叫迟绑定. 运行时多态或迟绑定.动态绑定 在C#语音中,运行时 ...
- C++中的动态类型与动态绑定、虚函数、运行时多态的实现
动态类型与静态类型 静态类型 是指不需要考虑表达式的执行期语义,仅分析程序文本而决定的表达式类型.静态类型仅依赖于包含表达式的程序文本的形式,而在程序运行时不会改变.通俗的讲,就是上下文无关,在编译时 ...
- iOS执行时与method swizzling
C语言是静态语言,它的工作方式是通过函数调用,这样在编译时我们就已经确定程序怎样执行的.而Objective-C是动态语言,它并不是通过调用类的方法来执行功能,而是给对象发送消息,对象在接收到消息之后 ...
- c#中运行时编译时 多态
c#中运行时编译时 多态 public class aa { } public class bb:aa { } public class cc { public static void Main( ...
- Java编译时多态和运行时多态
来源:https://blog.csdn.net/wendizhou/article/details/73733061 编译时多态:主要是方法的重载,通过参数列表的不同来区分不同的方法. 运行时多态: ...
随机推荐
- Solidworks如何在自定义的基准面上创建3D草图
1 选择某个基准面 右击"基准面上的3D草图" 2 当基准面出现黄色框即为正确.
- MPTCP 理解
背景 随着技术的发展许多设备具有了多个网络接口,而TCP依然是一个单线路的协议,在TCP的通信过程中发端和收端都 不能随意变换地址.我们可以利用多个网络接口的这一特性来改善性能和有效冗余.例 ...
- SQL语句练习手册--第一篇
表架构 Student(S#,Sname,Sage,Ssex) 学生表 Course(C#,Cname,T#) 课程表 SC(S#,C#,score) 成绩表 Teacher(T#,Tname) 教师 ...
- Step 2---有关Github的几个问题
1.取得项目的Git仓库的方式 第一种是在现存的目录下,通过导入所有文件来创建新的 Git 仓库. 要对现有的某个项目开始用 Git 管理,只需到此项目所在的目录,执行: $ git init 初始化 ...
- 微信小程序 之 请求函数封装
封装的request的代码 /** * @desc API请求接口类封装 */ /** * POST请求API * @param {String} url 接口地址 * @param {Object} ...
- DNS主从服务器+mysql
1 .背景 BIND从文本文件中获取数据,这样容易因为编辑错误出现问题. BIND需要将数据加载到内存中,如果域或者记录较多,会消耗大量的内存. BIND启动时解析Zone文件,对于一个记录较多的DN ...
- 局部敏感哈希(Locality-Sensitive Hashing, LSH)方法介绍(转)
局部敏感哈希(Locality-Sensitive Hashing, LSH)方法介绍 本文主要介绍一种用于海量高维数据的近似最近邻快速查找技术——局部敏感哈希(Locality-Sensitive ...
- asp.net 导出excel 中文乱码解决方法 (转)
用我转载的上一篇文章 Asp.net中把DataTable或DataGrid导出为Excel 导出的文档,中文有乱码现象,其实要解决中文乱码很简单,设置一下字符集.如下: // 设置编码和附件格式 c ...
- 我们常用的在a标签中有点击事件
我们常用的在a标签中有点击事件:1. a href="javascript:js_method();" 这是我们平台上常用的方法,但是这种方法在传递this等参数的时候很容易出问题 ...
- 按“开始”-“运行”,或按WIN+R,在[运行]窗口中输入
command--------CMD命令提示符 ipconfig查看本机IP chkdsk.exe-----Chkdsk磁盘检查 certmgr.msc----证书管理实用程序 calc--- ...