您的位置:首页 > 移动开发 > Objective-C

IOS开发学习笔记(十二)——ObjectC中的复杂类型

2013-07-09 19:49 399 查看
简单类型就不说了,基本上每个语言都差不多。本次我们仅讨论非简单数据类型。

类的继承

头文件

#import <Foundation/Foundation.h>

// MyDummy类从NSObject继承而来
@interface MyDummy : NSObject

/*
* '-'标识是实例方法而不是静态方法;
* 返回值用'()'括号括起来,后面跟上方法名;
* 冒号后跟上第一个参数类型(继续使用括号括起来)和参数
* 空格后跟第二个参数+冒号+类型+参数名
* 最后用分号结束
*/
- (void)foo:(NSString *)username password:(NSString *)passwd;

@end

实现文件

#import "MyDummy.h"

@implementation MyDummy

/*
* 根据声明生成
*/
-(void)foo:(NSString *)username password:(NSString *)passwd {
NSLog(@"Your name is %@, your password is %@", username, passwd);
}

@end

测试文件

#import <Foundation/Foundation.h>
#import "MyDummy.h"

int main(int argc, const char * argv[])
{

@autoreleasepool {
NSString *username = [[NSString alloc] initWithFormat:@"Sam"];
NSString *password = [[NSString alloc] initWithFormat:@"sssssssssss"];

MyDummy *dummy = [[MyDummy alloc] init];

[dummy foo:username password:password];

}
return 0;
}


Category

category和继承有部分类似,不过相对来说比继承关系要简单,我们看一下:

头文件

#import "MyDummy.h"

// 注意声明方式与继承不同
@interface MyDummy (MyDummy_SayHello)
// 方法的声明方式完全相同
-(void) sayHello:(NSString *)username password:(NSString *)password;

@end


实现文件

#import "MyDummy+MyDummy_SayHello.h"

@implementation MyDummy (MyDummy_SayHello)

-(void) sayHello:(NSString *)username password:(NSString *)password {
// 直接调用现有Dummy方法
return [self foo:username password:password];
}

@end

测试文件

#import <Foundation/Foundation.h>
#import "MyDummy.h"
#import "MyDummy+MyDummy_SayHello.h"

int main(int argc, const char * argv[])
{

@autoreleasepool {
NSString *username = [[NSString alloc] initWithFormat:@"Sam"];
NSString *password = [[NSString alloc] initWithFormat:@"sssssssssss"];
// 声明一个Dummy类的对象
MyDummy *dummy = [[MyDummy alloc] init];
// 对象的方法被扩展了
[dummy sayHello:username password:password];

}
return 0;
}


Protocol--协议

Protocol在java中对应的是接口。我们在ObjectC中这样使用:

定义protocol

#import <Foundation/Foundation.h>

@protocol IComparable <NSObject>

-(int) compare:(NSObject *)other;

@end


实现类的头文件
#import <Foundation/Foundation.h>
#import "IComparable.h"

@interface MyNumber : NSObject <IComparable>

@property int num;

-(int) compare:(NSObject *)other;

@end


实现类的实现文件

#import "MyNumber.h"
#import "IComparable.h"

@implementation MyNumber

@synthesize num;

-(int) compare:(NSObject *)other {
MyNumber *number = (MyNumber *) other;

return [self num] - [number num];
}

@end


测试类

#import <Foundation/Foundation.h>
#import "MyDummy.h"
#import "MyDummy+MyDummy_SayHello.h"
#import "MyNumber.h"

int main(int argc, const char * argv[])
{

@autoreleasepool {

MyNumber *num1 = [[MyNumber alloc] init];
MyNumber *num2 = [[MyNumber alloc] init];

[num1 setNum:10];
[num2 setNum:100];

NSLog(@"the number is %d", [num1 compare: num2]);
}
return 0;
}


id(动态类型)

ID类型很常见,例如alloc方法,init方法。ID类型很像以前Object Pascal中的variable类型,可以代表任意一种类型;或者你可以将他看成Java中的Object类型。但是一个很明显的差别在于:Java是强类型语言,所以所有的类型转换、方法调用都会检查类型;但ObjectC中,只要你将一个变量定义为id,那么编译器不会再做类型检查工作,甚至连warning都不抛出。

我们看看代码:

父类

#import <Foundation/Foundation.h>

@interface ParentClass : NSObject

@end

#import "ParentClass.h"

@implementation ParentClass

@end

第一个子类

#import "ParentClass.h"

@interface Child1 : ParentClass

-(void) foo1;

@end

#import "Child1.h"

@implementation Child1

-(void) foo1 {
NSLog(@"foo1 invoked.");
}

@end

第二个子类

#import "ParentClass.h"

@interface Child2 : ParentClass

-(void) foo2;

@end

#import "Child2.h"

@implementation Child2

-(void) foo2{
NSLog(@"foo2 invoked.");
}

@end

测试代码

#import <Foundation/Foundation.h>
#import "ParentClass.h"
#import "Child1.h"
#import "Child2.h"

int main(int argc, const char * argv[])
{

@autoreleasepool {

NSLog(@"child1");
Child1 *child1 = [[Child1 alloc] init];
[child1 foo1];
// 下面这一句无法编译
// [child1 foo2];

NSLog(@"child2");
id child2 = [[Child2 alloc] init];
// 下面这一句会爆出异常
// [child2 foo1];
[child2 foo2];

NSLog(@"child3");
id child3 = [[Child2 alloc] init];
// 下面这一段先判断类型,之后调用,安全
if ([child3 isKindOfClass:[Child1 class]]) {
// 下面这句不会调用
[child3 foo1];
}
// 下面这一段先判断是否包含指定方法,之后调用,同样安全
if ([child3 respondsToSelector:@selector(foo2)]) {
// 下面这句会调用
[child3 foo2];
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息