首页 > 代码库 > objective C中继承、协议、分类和多态的实现

objective C中继承、协议、分类和多态的实现

第一、objective C中继承的实现
在oc中只有实例变量会有权限控制,实例方法和类方法是没有权限控制的,这点与c++不同,OC默认的是protected,并且在声明权限控制时,没有分号
在OC中可以像C++一样用指针运算法来访问实例变量
Rectangle.h 文件代码:
#import <Foundation/Foundation.h>


@interface Rectangle : NSObject
{
    int _width;
    int _height;
}
@property (nonatomic,assign) int width;
@property (nonatomic,assign) int height;
-(Rectangle *) initWithWidth:(int)w AndHeight:(int)h;
-(void) print;
@end
Rectangle.m 文件代码:


#import "Rectangle.h"


@implementation Rectangle
@synthesize width=_width;
@synthesize height=_height;
-(Rectangle *) initWithWidth:(int)w AndHeight:(int)h
{
    self=[super init];
    if(self)
    {
    self.width=w;
    self.height=h;
    }
    return self;
}
-(void)print
{
    NSLog(@"the height is %d ,the width is %d",self.height,self.width);
}
@end


Square.h 文件代码:
#import "Rectangle.h"


@interface Square : Rectangle
{
    int _d;

-(Square *)initSquareWithwidth:(int)w AndHeight:(int)h Andval:(int)d;
@property (nonatomic,assign)int d;
@end


Square.m 文件代码:
#import "Square.h"


@implementation Square
@synthesize d=_d;
-(Square*)initSquareWithwidth:(int)w AndHeight:(int)h Andval:(int)d
{
    self=[super init];
    if(self)
    {
    self.height=h;
    self.width=w;
    self.d=d;
    }
    return self;
}
-(void)print //实现重载
{
    NSLog(@"the d is %d,the width is %d,the height is %d",self.d,self.width,self.height);
}
@
main函数:


#import <Foundation/Foundation.h>
#import "Access.h"
#import "Rectangle.h"
#import "Square.h"
int main(int argc, const char * argv[])
{


    @autoreleasepool {
        Rectangle *test=[[Rectangle alloc] init];
        [test initWithWidth:3 AndHeight:4];
        [test print];
        Square *squareObj=[[Square alloc] init];
        [squareObj initSquareWithwidth:3 AndHeight:4 Andval:5];
        [squareObj print];
    }
    return 0;
}


第二、objective C 协议的实现


在OC中不可以实现多重继承,因为是实现多重继承代价太大,但OC可以实现多个协议,协议类似于C++中的纯虚类,只有方法定义,没有方法实现,只有.h文件,没有成员变量。
协议(protocal)与Java的interface(接口)和C++的纯虚类相同,协议只负责方法的列表,不负责方法的实现,目的是让别的类来实现,协议只有接口部分,没有m文件,关键字是protocol,协议可以继承别的协议,协议中不能定义别的成员变量。
协议本身不是类,它是定义了一个其他类可以实现的接口
协议可以被任何类去实现
协议的关键字:
@required:表示必须强制实现的方法
@optional:表示可以有选择性实现的方法


Graphics.h file 
#import <Foundation/Foundation.h>


@protocol Graphics


-(void) onDraw;
@end
Ellipse 类的实现
#import <Foundation/Foundation.h>
#import "Graphics.h"


@interface Ellipse:NSObject <Graphics>


@end


#import "Ellipse.h"


@implementation Ellipse
-(void)onDraw
{
    NSLog(@"draw ellipse");
}
@end


Triangle类的实现
#import <Foundation/Foundation.h>
#import "Graphics.h"


@interface Triangle : NSObject <Graphics>


@end




#import "Triangle.h"


@implementation Triangle
-(void)onDraw
{
    NSLog(@"draw triangle");
}


@end


main函数的实现
int main(int argc, const char * argv[])
{


    @autoreleasepool {
        id test;
        test=[[Ellipse alloc] init];
        [test onDraw];
        [test release];
        
        test=[[Triangle alloc]init];
        [test onDraw];
        [test release];
         
    }
    
    return 0;
}
the resutl is:
draw ellipse
draw triangle
objective C的继承是单一继承,但是可以实现多个协议,用,分割


第三、objective-C中分类的实现
分类机制允许向一个类文件中添加新的方法声明,它不需要使用子类机制,并且在类实现的文件中的同一个名字下定义这些方法。
定义方法:
 #interface 类名(分类标示)  只要分类标示,就可以添加不同的分类方法


分类机制的缺点:
1. 不能添加属性,只能添加方法
2. 名称冲突,如果类别中方法与现有的方法重名,当发生名称冲突时,类别具有更高的优先级


分类机制的好处:
1.将类的实现分散到多个不同文件或多个不同框架中去实现
2.创建对私有方法的前向引用
3.面向对象添加非正式协议


#import “ClassName.h”
@interface ClassName (CategoryName)
@end
Vector.h 代码
#import <Foundation/Foundation.h>


@interface Vector : NSObject
{
    double _vec1;
    double _vec2;
}
@property (nonatomic,assign) double vec1;
@property (nonatomic,assign) double vec2;
-(Vector *)add:(Vector *)v;
-(void)setVec1:(double)vec1 AndVec2:(double)vec2;
-(void)print;
@end
Vector.m 代码


#import "Vector.h"


@implementation Vector
@synthesize vec1=_vec1;
@synthesize vec2=_vec2;
-(void)print
{
    NSLog(@"v1 value is %f,v2 value is %f",self.vec1,self.vec2);
}


-(void)setVec1:(double)vec1 AndVec2:(double)vec2
{
    self.vec1=vec1;
    self.vec2=vec2;
}
-(Vector*)add:(Vector *)v
{
    Vector *vector=[[Vector alloc]init];
    vector.vec1=v.vec1+self.vec1;
    vector.vec2=v.vec2+self.vec2;
    return vector;
}


@end
vector+sub.h 代码
#import <Foundation/Foundation.h>
#import "Vector.h"
@interface Vector(sub)


-(Vector *)sub:(Vector *)v;
@end


vector+sub.m code


#import "Vector+sub.h"


@implementation Vector (sub)
-(Vector *)sub:(Vector *)v
{
    Vector *temp=[[Vector alloc ]init];
    temp.vec1=self.vec1-v.vec1;
    temp.vec2=self.vec2-v.vec2;
    return temp;
}


@end


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


    @autoreleasepool {
        Vector *test1=[[Vector alloc]init];
        [test1 setVec1:2.2 AndVec2:3.4];
        [test1 print];
        Vector *test2=[[Vector alloc]init];
        [test2 setVec1:1.1 AndVec2:1.2];
        Vector *ret=[test1 sub:test2];
        [ret print];
        [test1 release];
        [test2 release];
        
    }
    
    return 0;
}
result:
2013-05-06 17:38:34.751 Access[2057:303] v1 value is 2.200000,v2 value is 3.400000
2013-05-06 17:38:34.753 Access[2057:303] v1 value is 1.100000,v2 value is 2.200000


如果想给类通过分类添加更多的函数,sample:
NSString+Utilities.h
#import <Foundation/Foundation.h>


@interface NSString(Utilities)
-(BOOL)isURL;


@end


#import "NSString+Utilities.h"


@implementation NSString(Utilities)
-(BOOL)isURL
{
    if ([self hasPrefix:@"http"])
    {
        return TRUE;
    }else
    {
        return FALSE;
    }
}


@end


这样就可以添加很多函数
分类是C++没有的概念,分类的使用是通过Objective-C的动态绑定实现,通过分类能够实现比继承更好的效果 


第四、objective c中多态的实现


动态类型:OC在运行时才确定对象的实际类型,如 id car,此时只有在执行到该语句时,我们才知道其实际类型
动态绑定:程序在执行时才确定对象调用的实际方法
在编译时就能确定的类型是静态类型,如 student *stu;这就是一个静态类型


Graphics.h 文件代码:
#import <Foundation/Foundation.h>


@interface Graphics : NSObject


-(void) onDraw;
@end
Graphics.m 文件代码:


#import "Graphics.h"


@implementation Graphics


@end


Triangle.h 代码:
#import "Graphics.h"


@interface Triangle : Graphics


@end
Triangle.m 代码:
#import "Triangle.h"


@implementation Triangle
-(void)onDraw
{
    NSLog(@"draw triangle");
}


@end
Ellipse.h 代码:


#import "Graphics.h"


@interface Ellipse : Graphics


@end
Ellipse.m 代码:




#import "Ellipse.h"


@implementation Ellipse
-(void)onDraw
{
    NSLog(@"draw ellips");
}
@end






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


    @autoreleasepool {
        Graphics *graphics;
        graphics=[[Ellipse alloc] init];
        [graphics onDraw];
        [graphics release];
        
        graphics=[[Triangle alloc] init];
        [graphics onDraw];
        [graphics release];
        
        id test;
        test=[[Ellipse alloc] init];
        [test onDraw];
        [test release];
        
        test=[[Triangle alloc] init];
        [test onDraw];
        [test release];
        
    }
    
    return 0;
}
输出结果:
2013-05-05 19:25:05.941 Access[966:303] draw ellips
2013-05-05 19:25:05.943 Access[966:303] draw triangle
2013-05-05 19:25:05.944 Access[966:303] draw ellips
2013-05-05 19:25:05.944 Access[966:303] draw triangle


id 类型属于ios常用的三大类型之一,其他包括:基本类型和对象类型,id类型可以代表任意的对象类型,该类型常用来实现多态







objective C中继承、协议、分类和多态的实现