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 [email protected](eat);//先将数据封装成SEL类型,获得方法的地址

BOOL isRespond1=[dog respondsToSelector:s1];//eat是Dog里面的方法,dog是Dog的实例对象,所以可以访问

NSLog(@"isRespond1 = %d",isRespond1);//输出为1

SEL [email protected](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 [email protected](abc);//abc方法是Animal中的

BOOL isRespond5=[Dog instancesRespondToSelector:s3];//子类继承父类的abc方法,自然子类可以调用(★这里我要说明一点,如果你在父类中只写了abc方法的声明,而没有写实现的话,这里结果就是0,表示无法调用★)

NSLog(@"isRespond5 = %d",isRespond5);//输出为1

//*******************************************************

}

return 0;

}

———————————————————————————————————————————

响应方法(属于动态类型检测部分)

#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 [email protected](run);//③

BOOL isRespond=[ani respondsToSelector:s1];//②

if (isRespond) {//④

[ani performSelector:s1];//⑤      实例对象调用无参方法

}

else

{

NSLog(@"无法调用!");

}

//*******************************************************

Dog *dog=[[Dog alloc]init];

SEL [email protected](eat:);//这里获取含多个参数的方法地址的时候,只写方法名即可

BOOL isRespond2=[dog respondsToSelector:s2];

if (isRespond2) {

[dog performSelector:s2 withObject:@"coffee"];//实例对象调用含有一个参数的方法

}

else

{

NSLog(@"无法调用!");

}

//*******************************************************

Dog *dog2=[[Dog alloc]init];

SEL [email protected](eat:andDogName:);//只写方法名

BOOL isRespond3=[dog respondsToSelector:s3];

if (isRespond3) {

[dog performSelector:s3 withObject:@"hotdog" withObject:@"bigmax"];//实例对象调用含两个参数的方法

}

else

{

NSLog(@"无法调用!");

}

//*******************************************************

}

return 0;

}

———————————————————————————————————————————

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-10 11:11:57

Objective-C 【动态类型检测&响应方法】的相关文章

OC 动态类型和静态类型

多态 允许不同的类定义相同的方法 动态类型 程序直到执行时才能确定所属的类 静态类型 将一个变量定义为特定类的对象时,使用的是静态形态 将一个变量定义为特定类的对象时,使用的是静态类型,在编译的时候就知道这个变量所属的类,这个变量总是存储特定类的对象.使用静态类型时,编译器尽可能的确保变量的用法在程序中始终保持一致,编译器能够通过检查来确定应用于对象的方法是由该类定义的或者由该类继承的,否则就会显示警告,静态类型能够更好地在程序编译阶段就指出错误.并且使用静态类型可以提高程序的可读性 简单来说:

Objective-C中的多态、点语法和动态类型总结

一. 多态 1. 多态概念,定义 什么是多态:多态就是某一类事物的多种形态: 表现形式:  Animal *ani = [Dog new]; 多态条件:1.有继承关系     2.有方法的重写 2.多态代码实现: //实例化猫的对象 Animal *animal  = [Cat new]; //父类的指针指向子类对象: [animal eat]; //实例化狗的对象 animal = [Dog new]; //父类的指针指向子类对象. [animal eat]; 3.多态注意点: 1) 如果存在

黑马程序员---OC基础5【点语法】【@property关键字】【@synthesize关键字】【id类型】【动态类型】【构造方法】

------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- [点语法] 1 1.使用“点语法” 2 Student *stu= [[Student alloc]init]; 3         //调用set方法 4         [stu setAge:20]; 5         [stu setName:@"Jone"]; 6         //点语法:xcode的特性,Xcode帮我们做了代码替换 7         //点语法,

C++--第27课 - 动态类型识别

第27课 - 动态类型识别 问题:下面的程序有问题吗? class Parent { public: virtual -Parent() { } }; class Child : public Parent { }; void test(Parent* p) { Child* c = (Child*)p;  //将父类强制转化为子类 } 1. 动态类型 由于基类指针可以直接指向派生类对象,因此可能存在指针所指类型与具体指向的对象类型不同的情况. (p指向的静态类型为Parent)Parent*

STUN: NAT 类型检测方法

STUN(Simple Transversal of UDP through NATs)[21]是RFC3489 规定的一种NAT 穿透方式,它采用辅助的方法探测NAT 的IP 和端口. STUN 的探测过程需要有一个公网IP的STUN 服务器,在NAT 后面的客户端必须和此服务器配合,互相之间发送若干个UDP数据包. UDP 包中包含有客户端需要了解的信息,比如NAT 外网IP,PORT 等等.客户端通过是否得到这个UDP 包和包中的数据判断自己的NAT 类型. 前提条件:有一个公网的Serv

多态 这是动态语言和静态语言(例如Java)最大的差别之一。动态语言调用实例方法,不检查类型,只要方法存在,参数正确,就可以调用。

多态 类具有继承关系,并且子类类型可以向上转型看做父类类型,如果我们从 Person 派生出 Student和Teacher ,并都写了一个 whoAmI() 方法: class Person(object): def __init__(self, name, gender): self.name = name self.gender = gender def whoAmI(self): return 'I am a Person, my name is %s' % self.name clas

C#在运行时动态创建类型的实现方法

本文实例讲述了C#在运行时动态创建类型的实现方法.是C#项目开发中很实用的技巧.分享给大家供大家参考.具体分析如下: 具体来说, C# 在运行时动态的创建类型是通过动态生成C#源代码,然后通过编译器编译成程序集的方式实现动态创建类型的 . 主要功能代码如下: public static Assembly NewAssembly() { //创建编译器实例. provider = new CSharpCodeProvider(); //设置编译参数. cp = new CompilerParame

OC多态,动态类型绑定

// //  main.m //  OC7类 // //  Created by Zoujie on 15/8/23. //  Copyright (c) 2015年 Zoujie. All rights reserved. // #import <Foundation/Foundation.h> #import "Fraction.h"//导入头文件 #import "Complex.h" #define Choose  0 int main(int 

动态类型 动态绑定 动态加载

1.动态类型运行时才知道,对象的类型,动态类型在编程中非常常见,简单的说就是id类型 比如代理在自定的时候就是,id类型.当前我们有时候自己定的方法,不确定,传进来的是什么类型的对象,我们也id类型,然后在方法内部去确定类型 2.动态绑定 对象被实例化后,就确定的对象类型,也确定了对象的属性和响应方法.这就是动态绑定. 说白也就是对象的确定了后,会绑定对应的属性和方法.那么我们也就可以动态的去给对象添加和实现方法.Class_addMethod 和 Method_setImplementatio