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

简单类型就不说了,基本上每个语言都差不多。本次我们仅讨论非简单数据类型。


类的继承


头文件

#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;
}


你可能感兴趣的:(继承,数据类型,category,objectc,protocal)