LHF Objective-C语法(7)id类型、动态判断与选择器
1、id类型
// Complex.h============================== #import <Foundation/Foundation.h> @interface Complex : NSObject{ double real; double imageinary; } -(Complex*) initWithReal:(double) r andImageinary:(double)i; -(void)setReal:(double) r; -(void)setImaginary:(double) i; -(void)setReal:(double)r andImaginary:(double) i; -(double)real; -(double)imaginary; -(void)print; @end // Complex.h============================== #import "Complex.h" @implementation Complex -(Complex*) initWithReal:(double) r andImageinary:(double)i; { self = [super init]; if(self){ [self setReal:r andImaginary:i]; } return self; } -(void)setReal:(double) r{ real = r; } -(void)setImaginary:(double) i{ imaginary = i; } -(void)setReal:(double)r andImaginary:(double) i{ real = r; imaginary = i; } -(double)real{ return real; } -(double)imaginary{ return imaginary; } -(void)print{ NSLog(@"%f + %fi",real,imaginary); } @end // main.m============================== #import "Fraction.h" #import "Complex.h" int main(argc,const char * argv[]){ Fracion *frac = [[Fraction alloc] intiWithNumerator:3 andDenominator:5]; Complex *comp = [[Complex alloc] initWithReal:1.5 andImaginary:3.5]; id number = frac; [number print]; number = comp; [comp print]; [frc release]; [comp release]; return 0; }
number先指向frac实例,调用了他的print方法,然后指向comp实例,调用了他的print
2、动态判断与选择器
假如别人传递给你一个id,你如何动态判断这个在运行时传递过来的对象到底有没有xxx方法那?
其实NSObject中有一系列这样的方法用于动态判断,类似java的反射机制
-(BOOL)isMemberOfClass:(Class) clazz //判断对象是否是clazz的实例,不包含子类的实例
-(BOOL)isKindOfClass:(Class) clazz //判断对象是否是clazz的实例或子类的实例
-(BOOL)respondsToSelector:(SEL) selector //判断类型或对象是否能够回应某个方法,这个方法使用选择器表示
+(BOOL)instancesRespondToSelector:(SEL) selector//判断类型所产生的实例是否能够回应某个方法,这个方法使用选择器表示
-(id)performSelector:(SEL) selector //用于动态调用类型或者对象上的一个方法
解释:
SEL类型,用于表示objc的一个方法
@selector(方法名) 例如:@selector(initWithWidth:andHeight:)不要丢掉冒号啊
Class id SEL 前不需要加星号
@import "MySquare.h" int main(argc,const char * argv[]){ MyRectangle *rec = [[MyRectangle alloc] initWithWidth:2 andHeight:5]; [rec area]; MySquare *squa = [[MySquare alloc] initWithSize:6]; [squa area]; //判断对象是否是clazz的实例,不包含子类的实例 if([squa isMemberOfClass:[MyRectangle class]]){ NSLog(@"squa isMemberOfClass MyRectangle."); }else{ NSLog(@"squa not isMemberOfClass MyRectangle."); } if([squa isKindOfClass:[MySquare class]]){ NSLog(@"squa isKindOfClass MySquare."); }else{ NSLog(@"squa not isKindOfClass MySquare."); } //判断对象是否是clazz的实例或者子类的实例 if([squa isKindOfClass:[MyRectangle class]]){ NSLog(@"squa isKindOfClass MyRectangle."); }else{ NSLog(@"squa not isKindOfClass MyRectangle."); } if([squa isKindOfClass:[MySquare class]]){ NSLog(@"squa isKindOfClass MySquare."); }else{ NSLog(@"squa not isKindOfClass MySquare."); }
//判断对象或类型是否有能力回应指定方法 if([squa respondsToSelector:@selector(initWithSize:)]){ NSLog(@"YES"); }else{ NSLog(@"NO"); } if([MySquare respondsToSelector:@selector(alloc)]){ NSLog(@"YES"); }else{ NSLog(@"NO"); } if([rec respondsToSelector:@selector(initWithWidth:andHeight:)]){ NSLog(@"YES"); }else{ NSLog(@"NO"); } //判断类产生的实例是否有能力回应指定的方法 if([MySquare instanceRespondsToSelector:@selector(initWithSize:)]){ NSLog(@"YES"); }else{ NSLog(@"NO"); } if([MySquare instanceRespondsToSelector:@selector(alloc:)]){ NSLog(@"YES"); }else{ NSLog(@"NO"); } //动态调用类或者对象上的一个方法 id x_id = [rec performSelector:@selector(area)]; [MyRectangle performSelector:@selector(alloc)]; [rec release]; [squa release];
4、类别
想扩充一个类的功能,但有不想使用继承,就可以选择类别
写一个Fraction的类别,为Fraction类增加两个方法
//FractionMath.h===================================== #import "Fraction.h" @interface Fraction(Math1) -(Fraction*)mul:(Fraction*)f;//乘法,就是传入一个Fraction作为参数,与当前Fraction进行计数 -(Fraction*)div:(Fraction*)f;//除法 @end @interface Fraction(Math2) -(Fraction*)add:(Fraction*)f; @end //FractionMath.m ======================================= #import "Fraction.h" @implementation Fraction(Math1) -(Fraction*)mul:(Fraction*)f{ return [[Fraction alloc] initWithNumerator:numerator *[f numerator] denominator:denominator*[f denominator]]; } -(Fraction*)div:(Fraction*)f{ return [[Fraction alloc] initWithNumerator:numerator *[f denominator] denominator:denominator*[f numerator]] } @end @implementation Fraction(Math2) -(Fraction*)add:(Fraction*)f{ return [[Fraction alloc] initWithNumerator: numerator *[f denominator] + denominator*[f numerator] denominator:denominator*[f denominator]]; } @end //main.m====================================== #import "FractionMath.h" int main(int argc,const char *argv[]){ Fraction *frac1 = [[Fraction alloc] initWithNumerator:1 denominator:3]; Fraction *frac2 = [[Fraction alloc] initWithNumerator:2 denominator:5]; Fraction *frac3 = [[frac1 mul:frac2]; [frac1 print]; NSLog(@"*"); [frac2 print]; NSLog(@"="); [frac3 print]; NSLog(@"\n"); Fration *frac5 = [frac1 add:frac2]; [frac2 print]; NSLog(@"+"); [frac2 print]; NSLog(@"="); [frac2 print]; NSLog(@"\n"); [frac1 release]; [frac2 release]; [frac3 release]; [frac5 release]; return 0; }
注意:
类别不可以声明新的实例变量,而且一旦你定义的方法与原始类中的方法名相同,那么原始方法将被隐藏起来
因为不是继承结构,你不能在类别中的方法使用super激活原始类的同名方法
类别还有一个功能,就是隐藏方法,我们在Fraction.m的最后增加如下方法
@interface Fraction(Math3)
-(Fraction*)sub:(Fraction*)f;//减法
@end
@implementation Fraction(Math3)
-(Fraction*)sub:(Fraction*)f{
return [[Fraction alloc] initWithNumerator:
numerator*[f denominator]-denominator*[f numerator]
denominator:denominator*[f denominator]];
}
@end
在。m文件中定义@interface?是的,因为@interface一旦定义在。m文件中,它就不能以header文件形式被导入到其他的类里了,
也就是这样的@interface中定义的方法相当于隐藏了,只有zhege。m编译单元内看见
}
转载于:https://www.cnblogs.com/landebug/archive/2012/02/14/2416671.html
LHF Objective-C语法(7)id类型、动态判断与选择器相关推荐
- Objective-C 点语法 成员变量的作用域 @property和@synthesize关键字 id类型
点语法 1.利用点语法替换set方法和get方法 方法调用 Student *stu = [Student new]; [stu setAge : 18]; int age = [stu age]; ...
- 黑马程序员——OC基础---核心语法(id,构造方法,Category,description,SEL)
------<a href="http://www.itheima.com" target="blank">Java培训.Android培训.iOS ...
- 通过创建动态类型 动态构建Expression Select表达式来控制Property可见性
通过创建动态类型 动态构建Expression Select表达式来控制Property可见性 项目中经常遇到的一个场景,根据当前登录用户权限,仅返回权限内可见的内容.参考了很多开源框架,更多的是在V ...
- python变量类型-【干货】Python基础语法之变量类型
原标题:[干货]Python基础语法之变量类型 还没关注? 01 Python编码 Python中默认的编码格式是 ASCII 格式,在没修改编码格式时无法正确打印汉字,所以在读取中文时会报错. 解决 ...
- 动态html函数的写法,如何将html div id的动态传递给js函数
我想将div id从html动态传递给js脚本 因为div id r1,r2,r3需要传入jS中的getElementById(),所以当用户鼠标放在任何div上,它会自动旋转.如何将html div ...
- Android NFC读MifareClassic卡获取卡片ID 类型 扇区 存储空间
1.首先要在AndroidManifest.xml中声明如下配置信息: 为了能够使用Android手机的NFC功能,需要在Manifest文件中添加相应的权限: 详细配置请参考-->Androi ...
- kan-java, 一个能裁剪语法特性的java动态编译工具
'kan-java' 就是 '砍-java' 这是一个java代码动态编译工具,也就是能够把String形式的java代码实时地编译为字节码的工具: "动态编译"工具,其实自jdk ...
- ts语法基础——基础类型
TS 语法 TS 基础类型 TypeScript 支持与 JavaScript 几乎相同的数据类型,此外还提供了实用的枚举类型方便我们使用 TS 支持的变量类型如下: 类型 描述 boolean 限制 ...
- Python中类型最佳判断方法
Python在定义变量的时候不用指明具体的的类型,解释器会在运行的时候会自动检查变量的类型,并根据需要进行隐式的类型转化,因为Python是动态语言,所以一般情况下是不推荐进行类型转化的. 比如进行& ...
最新文章
- 弹框--更新下载--安装
- 开发人员应该对IIS理论层的知识了解的多一些~第四讲 HttpModule中的几大事件
- Android菜单—Menu
- java生成带文字的图片_Java在背景图片上面加文字或者文字自动生成图片
- centos中使用rpm包或yum命令在线安装的软件默认是安装在那个目录下
- Python适合大数据处理吗?
- oracle两个date相减_从 Oracle 到 PostgreSQL:从 Uptime 到数据库实例运行时间
- 会计学硕和计算机,会计学与会计硕士有什么区别
- 【Citrix】XenCenter更新VM内存属性
- 丁香园 (http://www.dxy.cn)这个名字听着
- canvas小球绕斜椭圆轨迹运动
- 计算机上u盘打不开,u盘在电脑上打不开怎么解决
- 概率论考点之排列与组合
- git bash粘贴快捷键
- 法语学习笔记——语音
- 安卓开发良好的习惯(想到就更新)
- 百度网盘网页倍速播放视频的小技巧
- Java内存区域和GC机制
- 简单的Bat文件延迟启动特定程序
- 国瀚实业|工薪家庭理财资产配置攻略
热门文章
- 华为手机助手上架流程_2019年各大安卓应用商店上架经验,含流程,物料,方法,建议收藏...
- 求素数mdp c语言问题,C语言使用深度优先搜索算法解决迷宫问题(堆栈)
- html在线布局,HTML 布局
- 红外传感器型号和参数_浅析温度传感器原理
- STM8学习笔记---利用PWM功能输出SPWM波
- MyBatis中三种分页查询方式
- Java-网络编程总结(转载)
- Ubuntu下安装opencv3.4.6+opencv_contrib
- pytorch中的卷积操作详解
- DICOM协议资料汇集