动态类型调用方法的参数和返回值
来源:互联网 发布:无乃后乎句式 编辑:程序博客网 时间:2024/06/05 20:48
分数类
#import <Foundation/Foundation.h>@interface Fraction : NSObject@property int numerator,denominator;-(void) print;-(double) convertToNum;-(void) setNumerator:(int)n andDenominator:(int)d;-(Fraction *) add:(Fraction *)f;-(Fraction *) sub:(Fraction *)f;-(Fraction *) mul:(Fraction *)f;-(Fraction *) div:(Fraction *)f;-(void) reduce;@end
#import "Fraction.h"@implementation Fraction@synthesize numerator,denominator;-(void) print;{ NSLog(@"%i/%i",self.numerator,self.denominator);}-(double) convertToNum{ if (self.denominator!=0) { return (double)self.numerator/self.denominator; } else return NAN;}-(void) setNumerator:(int)n andDenominator:(int)d{ self.numerator=n; self.denominator=d;}-(Fraction *) add:(Fraction *)f{ Fraction *result=[[Fraction alloc] init]; result.numerator=self.numerator*f.denominator+self.denominator*f.numerator; result.denominator=self.denominator*f.denominator; [result reduce]; return result;}-(Fraction *) sub:(Fraction *)f{ Fraction *result=[[Fraction alloc] init]; result.numerator=self.numerator*f.denominator-self.denominator*f.numerator; result.denominator=self.denominator*f.denominator; [result reduce]; return result;}-(Fraction *) mul:(Fraction *)f{ Fraction *result=[[Fraction alloc] init]; result.numerator=self.numerator*f.numerator; result.denominator=self.denominator*f.denominator; [result reduce]; return result;}-(Fraction *) div:(Fraction *)f{ Fraction *result=[[Fraction alloc] init]; result.numerator=self.numerator*f.denominator; result.denominator=self.denominator*f.numerator; [result reduce]; return result;}-(void) reduce{ int u,v,temp; u=self.numerator; v=self.denominator; while (v!=0) { temp=u%v; u=v; v=temp; } self.numerator/=u; self.denominator/=u;}@end复数类
#import <Foundation/Foundation.h>@interface Complex : NSObject@property double real,imaginary;-(void) print;-(void) setReal:(double)r andImaginary:(double)i;-(Complex *) add:(Complex *)c;-(Complex *) sub:(Complex *)c;-(Complex *) mul:(Complex *)c;-(Complex *) div:(Complex *)c;@end
#import "Complex.h"@implementation Complex@synthesize real,imaginary;-(void) print{ NSLog(@"%g+%gi",self.real,self.imaginary);}-(void) setReal:(double)r andImaginary:(double)i{ self.real=r; self.imaginary=i;}-(Complex *) add:(Complex *)c{ Complex *result=[[Complex alloc] init]; result.real=self.real+c.real; result.imaginary=self.imaginary+c.imaginary; return result;}-(Complex *) sub:(Complex *)c{ Complex *result=[[Complex alloc] init]; result.real=self.real-c.real; result.imaginary=self.imaginary-c.imaginary; return result;}-(Complex *) mul:(Complex *)c{ Complex *result=[[Complex alloc] init]; result.real=self.real*c.real; result.imaginary=self.imaginary*c.imaginary; return result;}-(Complex *) div:(Complex *)c{ Complex *result=[[Complex alloc] init]; result.real=self.real/c.real; result.imaginary=self.imaginary/c.imaginary; return result;}@end
多态
不同的类可以定义同名的方法 如下
Fraction *f1=[[Fraction alloc] init]; Fraction *f2=[[Fraction alloc] init]; Fraction *f3; Complex *c1=[[Complex alloc] init]; Complex *c2=[[Complex alloc] init]; Complex *c3; [f1 setNumerator:1 andDenominator:10]; [f2 setNumerator:2 andDenominator:15]; [c1 setReal:18 andImaginary:2.5]; [c2 setReal:-5 andImaginary:3.2]; f3=[f1 add:f2]; c3=[c1 add:c2]; [f3 print]; [c3 print];
2015-03-20 13:12:48.074 TTTTTT[585:303] 7/302015-03-20 13:12:48.076 TTTTTT[585:303] 13+5.7i
Fraction类和Complex类都有add方法和print方法 根据对象所属的类 调用相对应的方法
动态类型(即id类型)
id类型其实就是一个指针 该指针可以存放任何类的对象
动态绑定
动态绑定其实质是 声明为id类型的对象 在编译时无法确定究竟存放了哪个类的对象 直到程序运行时才确定 还是那句话 根据id对象存放的对象所属的类 动态调用相对应的方法 如下
id result; result=[f1 add:f2]; [result print]; result=[c1 add:c2]; [result print];
2015-03-20 13:12:48.078 TTTTTT[585:303] 7/302015-03-20 13:12:48.079 TTTTTT[585:303] 13+5.7i动态类型调用方法需要注意一下几点
1、如果在多个类中具有同名方法 方法与方法之间的参数类型必须保持一致 返回值也必须保持一致性 一致性指的是 int对int double对double 指针对指针 否则编译器会报错 比如加入Calculator类 Calculator类中的add:方法-(double) add:(double)value与上面两个类的add:方法在参数和返回值上没有保持一致
2、在保持一致性的前提下 如果参数是静态类型 编译器仍旧会发出警告 因为编译器只认最先进入的那个头文件中的add:方法 如下
#import "Fraction.h"#import "Complex.h"
id resultFraction,resultComplex,result; resultFraction=[f1 add:f2]; resultComplex=[c1 add:c2]; [resultFraction print]; [resultComplex print]; resultFraction=[resultFraction add:f1]; resultComplex=[resultComplex add:c1]; [resultFraction print]; [resultComplex print];
2015-03-20 13:09:46.029 Meature[549:303] 7/302015-03-20 13:09:46.032 Meature[549:303] 13+5.7i2015-03-20 13:09:46.033 Meature[549:303] 1/32015-03-20 13:09:46.034 Meature[549:303] 31+8.2i最先进入的是Fraction头文件 所以编译器在遇到[resultComplex add:c1]会发出警告 表示不兼容的指针类型 Complex类型送入到Fraction类型参数之中 其实这里没有任何问题
3、如果参数也是id类型 那么编译器就不会发出警告 因为编译器不知道送入的指针类型 如下
result=[resultFraction add:resultFraction]; [result print]; result=[resultComplex add:resultComplex]; [result print];
2015-03-20 13:09:46.034 Meature[549:303] 2/32015-03-20 13:09:46.035 Meature[549:303] 62+16.4i关于类的问题
[对象 class]
获取当前对象的类对象 既可用于实例对象 也可用于类对象 如下
Class c=[f1 class]; NSLog(@"%@",c); c=[Fraction class]; NSLog(@"%@",c); NSLog(@"%@",[c1 class]); NSLog(@"%@",[Complex class]);
2015-03-20 17:05:15.634 TTTTTT[1098:303] Fraction2015-03-20 17:05:15.635 TTTTTT[1098:303] Fraction2015-03-20 17:05:15.636 TTTTTT[1098:303] Complex2015-03-20 17:05:15.637 TTTTTT[1098:303] Complex@selector(方法)
既可用于实例方法 也可用于类方法 如下
SEL s=@selector(setNumerator:andDenominator:); NSLog(@"%@",NSStringFromSelector(s)); NSLog(@"%@",NSStringFromSelector(@selector(setReal:andImaginary:)));
2015-03-20 17:05:15.639 TTTTTT[1098:303] setNumerator:andDenominator:2015-03-20 17:05:15.640 TTTTTT[1098:303] setReal:andImaginary:-(BOOL) isMemberOfClass:classObj 是否是classObj类的实例
-(BOOL) isKindOfClass:classObj 是否是classObj类或其子类的实例
+(BOOL) isSubclassOfClass:classObj 是否是classObj类的子类
+-(BOOL) respondsToSelector:selector 对象是否可以响应selector方法
+(BOOL) instancesRespondToSelector:selector 类的实例是否可以响应selector方法
+-(BOOL) respondsToSelector:selector 对象是否可以响应selector方法
+(BOOL) instancesRespondToSelector:selector 类的实例是否可以响应selector方法
其中respondsToSelector:既是实例方法又是类方法
方法包括从父类继承的方法
Square *squa=[[Square alloc] init]; NSLog(@"%@",[squa isMemberOfClass:[Square class]]?@"YES":@"NO"); NSLog(@"%@",[squa isMemberOfClass:[Rectangle class]]?@"YES":@"NO"); NSLog(@"%@",[squa isMemberOfClass:[NSObject class]]?@"YES":@"NO"); NSLog(@"%@",[squa isKindOfClass:[Square class]]?@"YES":@"NO"); NSLog(@"%@",[squa isKindOfClass:[Rectangle class]]?@"YES":@"NO"); NSLog(@"%@",[squa isKindOfClass:[NSObject class]]?@"YES":@"NO"); NSLog(@"%@",[Square isSubclassOfClass:[Rectangle class]]?@"YES":@"NO"); NSLog(@"%@",[Square isSubclassOfClass:[NSObject class]]?@"YES":@"NO"); NSLog(@"%@",[squa respondsToSelector:@selector(setSide:)]?@"YES":@"NO"); NSLog(@"%@",[squa respondsToSelector:@selector(setWidth:andHeight:)]?@"YES":@"NO"); NSLog(@"%@",[Square respondsToSelector:@selector(alloc)]?@"YES":@"NO"); NSLog(@"%@",[Square instancesRespondToSelector:@selector(setSide:)]?@"YES":@"NO"); NSLog(@"%@",[Square instancesRespondToSelector:@selector(setWidth:andHeight:)]?@"YES":@"NO");
2015-03-20 18:59:30.450 Rectangle[1194:303] YES2015-03-20 18:59:30.451 Rectangle[1194:303] NO2015-03-20 18:59:30.453 Rectangle[1194:303] NO2015-03-20 18:59:30.453 Rectangle[1194:303] YES2015-03-20 18:59:30.454 Rectangle[1194:303] YES2015-03-20 18:59:30.455 Rectangle[1194:303] YES2015-03-20 18:59:30.456 Rectangle[1194:303] YES2015-03-20 18:59:30.456 Rectangle[1194:303] YES2015-03-20 18:59:30.457 Rectangle[1194:303] YES2015-03-20 18:59:30.458 Rectangle[1194:303] YES2015-03-20 18:59:30.458 Rectangle[1194:303] YES2015-03-20 18:59:30.459 Rectangle[1194:303] YES2015-03-20 18:59:30.459 Rectangle[1194:303] YES接受者为类的方法之中 类也可以通过class方法来获取[squa class]或[Square class]
0 0
- 动态类型调用方法的参数和返回值
- 方法就是完成特定功能的代码块。 方法的格式: 修饰符 返回值的类型 方法名(参数类型 参数名1,参数类型 参数名2、、、、、、、、、 ){ 方法体; Return 返回值; } 赋值调用的格式:
- 指针类型的参数和返回值
- 反射机制获取方法的参数类型和返回值类型
- XFire实现自定义类型参数传递和调用返回自定义类型方法
- 方法中参数和返回类型的指导原则
- JavaDay03--Notes(数组的遍历和部分拷贝+方法的调用、参数和返回值)
- 方法的返回值和参数
- Java加载jar文件并调用jar文件当中有参数和返回值的方法
- Spring Boot系列九 spring mvc的@RequestMapping支持的方法参数类型和返回类型
- 形式参数和返回值的类型问题
- MyBatis的传入和返回参数类型
- 函数调用中参数和返回值的拷贝
- 让FLASH接收网页传过来的参数和动态调用外部脚本程序返回结果
- SpringMVC提高篇(二): 处理器方法支持的方法参数和返回类型
- 方法调用和返回值
- struts2的常量、动态方法调用、接受请求参数处理、类型转换
- struts2的常量、动态方法调用、接受请求参数处理、类型转换 .
- C语言宏定义时#(井号)和##(双井号)的用法
- 使基于导航栏的视图始终都能调用viewwillappear
- 鼠标按下Btn缩小,松开放大 代码
- 如何判断双链表是否有环
- linux socket编程client关闭时server崩溃问题
- 动态类型调用方法的参数和返回值
- 求转置矩阵问题
- mysql —— 分表分区
- netty in action第十二章-SPDY
- ASE 加密和解密流程
- windows实体机调试虚拟机内的应用程序
- 运行下列代码时将会产生什么样的输出?m/n*10
- -----ARM汇编伪指令----
- JAVA和C# 3DES加密解密