object-c的protocol(协议)

本文详细介绍了Objective-C中的协议概念,包括协议的声明、使用说明及例子代码。通过实例展示了如何在类中实现协议并运用协议进行类型约束。重点讲解了协议的特性、声明方式、使用场景以及如何在类中实现协议的方法。通过具体代码实例,深入理解协议在Objective-C编程中的实际应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在object-c中,协议的声明类似于类接口的声明,但是,协议没有父类,而且不能定义成员变量,只能定义成员函数,而且成员函数并不是在这个协议中实现,而是要在使用它的类中实现。 
1. 使用说明
   (1)协议的声明方式,在.h中:
       @protocol Myprotocol 
         -(void) myProtocolMethod;
       @end
   (2)协议的运用:
      如果要使用一个协议,就要在声明类的时候, 用<...>将协议名称列出,并且需要在这个类的实现中也必须同时实现协议中声明的成员函数。 
      例如,在你声明自己的类 MyClass的时候, 可以这样做: 
      @interface MyClass: NSObject <Myprotocol> 
      而在实现的 MyClass.m中,就需要实现协议Myprotocol中声明的方法myProtocolMethod。
2. 例子代码
//1. Printing.h
 @protocol Printing
-(void) print;
@end 


//2. Fraction.h
#import <Foundation/NSObject.h>
#import "Printing.h"


@interface Fraction: NSObject <Printing, NSCopying> {
    int numerator;
    int denominator;
}


-(Fraction*) initWithNumerator: (int) n denominator: (int) d;
-(void) setNumerator: (int) d;
-(void) setDenominator: (int) d;
-(void) setNumerator: (int) n andDenominator: (int) d;
-(int) numerator;
-(int) denominator;
@end


//3. Fraction.m
#import "Fraction.h"
#import <stdio.h>


@implementation Fraction
-(Fraction*) initWithNumerator: (int) n denominator: (int) d {
    self = [super init];


    if ( self ) {
        [self setNumerator: n andDenominator: d];
    }


    return self;
}


-(void) print {
    printf( "%i/%i", numerator, denominator );
}


-(void) setNumerator: (int) n {
    numerator = n;
}


-(void) setDenominator: (int) d {
    denominator = d;
}


-(void) setNumerator: (int) n andDenominator: (int) d {
    numerator = n;
    denominator = d;
}


-(int) denominator {
    return denominator;
}


-(int) numerator {
    return numerator;
}


-(Fraction*) copyWithZone: (NSZone*) zone {
    return [[Fraction allocWithZone: zone] initWithNumerator: numerator
                                           denominator: denominator];
}
@end


//4. Complex.h
#import <Foundation/NSObject.h>
#import "Printing.h"


@interface Complex: NSObject <Printing> {
    double real;
    double imaginary;
}


-(Complex*) initWithReal: (double) r andImaginary: (double) i;
-(void) setReal: (double) r;
-(void) setImaginary: (double) i;
-(void) setReal: (double) r andImaginary: (double) i;
-(double) real;
-(double) imaginary;
@end


//5. Complex.m
#import "Complex.h"
#import <stdio.h>


@implementation Complex
-(Complex*) initWithReal: (double) r andImaginary: (double) i {
    self = [super init];


    if ( self ) {
        [self setReal: r andImaginary: i];
    }


    return self;
}


-(void) setReal: (double) r {
    real = r;
}


-(void) setImaginary: (double) i {
    imaginary = i;
}


-(void) setReal: (double) r andImaginary: (double) i {
    real = r;
    imaginary = i;
}


-(double) real {
    return real;
}


-(double) imaginary {
    return imaginary;
}


-(void) print {
    printf( "%_f + %_fi", real, imaginary );
}
@end


//6. main.m
#import <stdio.h>
#import "Fraction.h"
#import "Complex.h"


int main( int argc, const char *argv[] ) {
    // create a new instance
    Fraction *frac = [[Fraction alloc] initWithNumerator: 3 denominator: 10];
    Complex *comp = [[Complex alloc] initWithReal: 5 andImaginary: 15];
    id <Printing> printable;
    id <NSCopying, Printing> copyPrintable;


    // print it
    printable = frac;
    printf( "The fraction is: " );
    [printable print];
    printf( "\n" );


    // print complex
    printable = comp;
    printf( "The complex number is: " );
    [printable print];
    printf( "\n" );


    // this compiles because Fraction comforms to both Printing and NSCopyable
    copyPrintable = frac;


    // this doesn't compile because Complex only conforms to Printing
    //copyPrintable = comp;


    // test conformance


    // true
    if ( [frac conformsToProtocol: @protocol( NSCopying )] == YES ) {
        printf( "Fraction conforms to NSCopying\n" );
    }


    // false
    if ( [comp conformsToProtocol: @protocol( NSCopying )] == YES ) {
        printf( "Complex conforms to NSCopying\n" );
    }


    // free memory
    [frac release];
    [comp release];


    return 0;
}



3. 编译运行
 gcc -fconstant-string-class=NSConstantString -c main.m -I /GNUstep/System/Library/Headers
gcc -c Complex.m -I /GNUstep/System/Library/Headers
gcc -c Fraction.m -I /GNUstep/System/Library/Headers
gcc main.o Complex.o Printing.o -o main -L /GNUstep/System/Library/Libraries/ -lobjc -lgnustep-base


$ ./main.exe
The fraction is: 3/10
The complex number is: _f + _fi
Fraction conforms to NSCopying
 
4. 说明
  (1). protocol没有父类,或者说是无类的; 
  (2). 如果一个类遵守了某个协议,那么这个类的子类也遵守该协议; 

  (3). protocol只需要在.h中声明就可以,所以,协议也不需要编译成.o,也不可能编译成.o,因为没有.m文件。 

  (4) . 正如例子中呈现的一样,你的类中可以使用多个protocol, 例如:

         @interface SomeClass <Protocol1, Protocol2, Protocol3>

            ...

        @end

       
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

liranke

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值