Objective-C 【动态类型检测&响应方法】
———————————————————————————————————————————
动态类型检测
代码:
#import <Foundation/Foundation.h>
@interface Animal : NSObject
-(void)run;
-(void)abc;
@end
@implementation Animal
-(void)run
{
NSLog(@"Animal run!");
}
-(void)abc
{
NSLog(@"abc!");
}
@end
@interface Dog : Animal
-(void)run;
-(void)eat;
-(void)bark;
@end
@implementation Dog
-(void)run
{
NSLog(@"Dog run!");
}
-(void)eat
{
NSLog(@"Dog eat!");
}
-(void)bark
{
NSLog(@"Dog bark!");
}
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
//动态类型检测:
//*******************************************************
// 1)判断某个对象是否是该类的实例对象,或者是其子类的实例对象(对象和类)
// isKindOfClass使用格式: [对象 isKindOfClass:类对象];
Animal *ani=[Animal new];
//BOOL isIstance=[ani isKindOfClass:[ani class]];
BOOL isInstance=[ani isKindOfClass:[Animal class]];
//上面两种写法都行,因为可以用 类类型的实例对象/类名 去调用类对象
NSLog(@"isInstance = %d",isInstance);//输出是1(ani本来就是Animal的实例对象,自然为1)
Dog *dog=[Dog new];
BOOL isInstance1=[dog isKindOfClass:[Animal class]];
NSLog(@"isIstance1 = %d",isInstance1);//输出是1(Dog是Animal的子类,dog是Dog的实例对象,自然为1)
Person *p=[Person new];
BOOL isInstance2=[p isKindOfClass:[Animal class]];
NSLog(@"isInstance2 = %d",isInstance2);//输出是0(Person是无关的类,不是Animal的子类,p是Person的实例对象,所以为0)
//*******************************************************
// 2)判断某个对象是否是该类的实例对象(单指这个类,不包括其子类)
// isMemberOfClass使用格式: [对象 isMemberOfClass:类对象];
BOOL isInstance3=[ani isMemberOfClass:[Animal class]];
NSLog(@"isInstance3 = %d",isInstance3);//输出是1(ani是Animal的实例对象,自然为1)
BOOL isInstance4=[dog isMemberOfClass:[Animal class]];
NSLog(@"isInstance4 = %d",isInstance4);//输出是0(dog是Dog的实例对象,Dog是Animal的子类,所以为0)
//*******************************************************
// 3)判断某个类是不是另一个类的子类
// isSubclassOfClass使用格式: [类名/类对象 isSubclassOfClass:类对象];
BOOL isInstance5=[Dog isSubclassOfClass:[Animal class]];
NSLog(@"isInstance5 = %d",isInstance5);//输出为1(Dog是Animal的子类)
BOOL isInstance6=[Animal isSubclassOfClass:[Dog class]];
NSLog(@"isInstance6 = %d",isInstance6);//输出为0(Animal是Dog的父类)
BOOL isInstance7=[[Dog class] isSubclassOfClass:[Animal class]];
NSLog(@"isInstance7 = %d",isInstance7);//输出为1(这里注意前面可以写作类对象的形式)
// BOOL isInstance8=[[Dog class] isSubclassOfClass:Animal];//这句话编译不会通过,因为后面Animal不是类对象的格式
//*******************************************************
// 4)判断对象能否响应指定的方法
// respondsToSelector使用格式: [对象 respondsToSelector:方法的SEL];
// BOOL isRespond1=ani respondsToSelector:<#(SEL)#>//这里显然参数传进来的应该是一个SEL的类型
// 我们一起来回顾一下SEL是什么。首先SEL表示方法的存储位置,我们一般先将方法包装为SEL类型,然后根据sel数据找到方法的地址,然后根据方法地址调用相应的方法。所以接下来我们应该这样处理:
SEL s1=@selector(eat);//先将数据封装成SEL类型,获得方法的地址
BOOL isRespond1=[dog respondsToSelector:s1];//eat是Dog里面的方法,dog是Dog的实例对象,所以可以访问
NSLog(@"isRespond1 = %d",isRespond1);//输出为1
SEL s2=@selector(bark);
BOOL isRespond2=[ani respondsToSelector:s2];//ani是Animal的实例对象,但是bark是Dog的特有方法,所以说无法访问
NSLog(@"isRespond = %d",isRespond2);//输出为0
// 所以说我们一般用实例对象调用方法之前,可以先作一个判断,如下:
// if(isRespond1)
// {
// [dog eat];
// }
// else
// {
// NSLog(@"无法调用");
// }
// 这样可以把错误扼杀在编译时,而不是到了运行的时候错误才发现。
//*******************************************************
// 5)判断类能否调用(相应)指定的方法
BOOL isRespond3=[Dog instancesRespondToSelector:s1];//s1是eat的SEL封装,eat是Dog的方法,所以可以调用
NSLog(@"isRespond3 = %d",isRespond3);//输出为1
BOOL isRespond4=[Animal instancesRespondToSelector:s1];//显然Animal不能调用其子类特有的方法
NSLog(@"isRespond4 = %d",isRespond4);//输出为0
SEL s3=@selector(abc);//abc方法是Animal中的
BOOL isRespond5=[Dog instancesRespondToSelector:s3];//子类继承父类的abc方法,自然子类可以调用(★这里我要说明一点,如果你在父类中只写了abc方法的声明,而没有写实现的话,这里结果就是0,表示无法调用★)
NSLog(@"isRespond5 = %d",isRespond5);//输出为1
//*******************************************************
}
return 0;
}
———————————————————————————————————————————
响应方法(属于动态类型检测部分)
//响应方法(调用方法)
//1.响应无参方法
//2.响应有一个参数的方法
//3.响应有两个参数的方法(因为OC只提供了最多两个参数的响应方法)
#import <Foundation/Foundation.h>
@interface Animal : NSObject
-(void)run;
@end
@implementation Animal
-(void)run
{
NSLog(@"Animal run!");
}
@end
@interface Dog : Animal
-(void)eat:(NSString *)foodName;
-(void)eat:(NSString *)foodName andDogName:(NSString *)dogName;
@end
@implementation Dog
-(void)eat:(NSString *)foodName
{
NSLog(@"Dog eat %@",foodName);
}
-(void)eat:(NSString *)foodName andDogName:(NSString *)dogName
{
NSLog(@"%@ eat %@",dogName,foodName);
}
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
// 以后调用方法,大都以这种形式调用
// 调用方法的时候,我们应该具备这样的思路,养成书写习惯:
// ①首先调用方法得有 实例对象,所以要先创建实例对象
// ②其次调用方法前要判断是否能调用,所以要有判断语句(对象是否能调用方法)
// ③因为判定对象能调用方法的时候这个方法是以SEL的格式去调用的,所以先要将此方法转化成SEL的形式
// ④然后判断结束后,返回值是1就调用,返回值是0就输出无法调用
// ⑤最后调用 无参/有参 方法(本节所讲内容)
//*******************************************************
Animal *ani =[[Animal alloc]init];//①
SEL s1=@selector(run);//③
BOOL isRespond=[ani respondsToSelector:s1];//②
if (isRespond) {//④
[ani performSelector:s1];//⑤ 实例对象调用无参方法
}
else
{
NSLog(@"无法调用!");
}
//*******************************************************
Dog *dog=[[Dog alloc]init];
SEL s2=@selector(eat:);//这里获取含多个参数的方法地址的时候,只写方法名即可
BOOL isRespond2=[dog respondsToSelector:s2];
if (isRespond2) {
[dog performSelector:s2 withObject:@"coffee"];//实例对象调用含有一个参数的方法
}
else
{
NSLog(@"无法调用!");
}
//*******************************************************
Dog *dog2=[[Dog alloc]init];
SEL s3=@selector(eat:andDogName:);//只写方法名
BOOL isRespond3=[dog respondsToSelector:s3];
if (isRespond3) {
[dog performSelector:s3 withObject:@"hotdog" withObject:@"bigmax"];//实例对象调用含两个参数的方法
}
else
{
NSLog(@"无法调用!");
}
//*******************************************************
}
return 0;
}
———————————————————————————————————————————
版权声明:本文为博主原创文章,未经博主允许不得转载。
Objective-C 【动态类型检测&响应方法】的更多相关文章
- 六.OC基础--1. id和instancetype类型,2.动态类型检测,3.响应方法,构造方法,4.重写构造方法,5.自定义构造方法
1. id和instancetype类型, id和instancetype类型区别: 1. id和instancetype都可以用来作为方法的返回值 2. id可以用来定义类型,instancetyp ...
- dynamic动态类型的扩展方法
对于一个动态类型来说,你可以认为它包含任意成员,它们都能通过编译.但到了运行时,到底是否拥有这些成员,就真相大白了.如 dynamic test = ; Console.Write(test.Name ...
- OC 动态类型和静态类型
多态 允许不同的类定义相同的方法 动态类型 程序直到执行时才能确定所属的类 静态类型 将一个变量定义为特定类的对象时,使用的是静态形态 将一个变量定义为特定类的对象时,使用的是静态类型,在编译的时候就 ...
- JS做类型检测到底有几种方法?看完本文就知道了!
JS有很多数据类型,对于不同数据类型的识别和相互转换也是面试中的一个常考点,本文主要讲的就是类型转换和类型检测. 数据类型 JS中的数据类型主要分为两大类:原始类型(值类型)和引用类型.常见的数据类型 ...
- C++基础知识:动态类型识别
1.动态类型指的是基类指针所指向的对象的实际类型 2.C++中的多态根据实际的对象类型调用对应的虚函数(1)可以在基类中定义虚函数返回具体的类型信息(2)所有的派生类都必须实现类型相关的虚函数(3)每 ...
- JavaScript中类型检测
文章首发: http://www.cnblogs.com/sprying/p/4349426.html 本文罗列了一般Js类型检测的方法,是构建Js知识体系的一小块,这篇文章是我很早之前总结的. 一. ...
- STUN: NAT 类型检测方法
STUN(Simple Transversal of UDP through NATs)[21]是RFC3489 规定的一种NAT 穿透方式,它采用辅助的方法探测NAT 的IP 和端口. STUN 的 ...
- 五.OC基础--1.多态,2.类对象,3.点语法,4.@property&@synthesize,5.动态类型,内省(判断对象是否遵循特定的协议,以及是否可以响应特定的消息)
五.OC基础--1.多态, 1. 多态概念,定义:多态就是某一类事物的多种形态: 表现形式: Animal *ani = [Dog new]; 多态条件:1.有继承关系 2.有方法的重写 2.多态代码 ...
- Asp.Net SignalR 使用记录 技术回炉重造-总纲 动态类型dynamic转换为特定类型T的方案 通过对象方法获取委托_C#反射获取委托_ .net core入门-跨域访问配置
Asp.Net SignalR 使用记录 工作上遇到一个推送消息的功能的实现.本着面向百度编程的思想.网上百度了一大堆.主要的实现方式是原生的WebSocket,和SignalR,再次写一个关于A ...
随机推荐
- SqlServer更新视图存储过程函数脚本
--视图.存储过程.函数名称 DECLARE @NAME NVARCHAR(255); --局部游标 DECLARE @CUR CURSOR --自动修改未上状态为旷课 SET @CUR=CURSOR ...
- Swift学习笔记二
Swift是苹果公司开发的一门新语言,它当然具备面向对象的许多特性,现在开始介绍Swift中类和对象的语法. 对象和类 用"class"加上类名字来创建一个类,属性声明和声明常量或 ...
- POJ 2195 D - Going Home 费用流
D - Going HomeTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hust.edu.cn/vjudge/contest/vie ...
- UVA 1557 - Calendar Game(博弈dp)
UVA 1557 - Calendar Game 题目链接 题意:给定一个日期,两个人轮流走,每次能够走一月或者一天,问最后谁能走到2001.11.4这个日子 思路:记忆化搜索,对于每一个日期,假设下 ...
- Android 滑动效果进阶篇(五)—— 3D旋转
前面介绍了利用Android自带的控件,进行滑动翻页制作效果,现在我们通过代码实现一些滑动翻页的动画效果. Animation实现动画有两个方式:帧动画(frame-by-frame animatio ...
- hdu 3006 枚举集合能够产生的全部并集的集合
http://acm.hdu.edu.cn/showproblem.php? pid=3006 刚买的CHERRY键盘 手感真好 可惜不习惯 写代码老是打错.一个题写了一上午,都是各种按错键DEBUG ...
- debian7编译内核
第一个步骤“配置内核”. 在这里,我比较建议在发行版默认的config的基础上再进行配置,这样 配置出的内核和发行版本身才会有更好的相容性.比如可以在运行“make menuconfig”之前执行命令 ...
- Branch and Bound:分支限界算法
http://blog.sciencenet.cn/blog-509534-728984.html 分支定界 (branch and bound) 算法是一种在问题的解空间树上搜索问题的解的方法.但与 ...
- 用PC浏览器模拟手机浏览器(一):无扩展版
想浏览手机版,打开对应网址却跳转到PC版?怎么办? 下面咱们来说下在只是安装了浏览器,无需其他安装操作的情况下来怎么用PC浏览器模拟手机浏览器,然后访问手机站点. 浏览器众多,IE系列的咱就不考虑了, ...
- PHP设计模式之策略模式
前提: 在软件开发中也常常遇到类似的情况,实现某一个功能有多种算法或者策略,我们可以根据环境或者条件的不同选择不同的算法或者策略来完成该功能.如查 找.排序等,一种常用的方法是硬编码(Hard Cod ...