标签:
分享类型:应用开发相关
1
2
3
4
5
6
7
8
|
// ViewControllerEx.h @interface ViewControllerEx : UIViewController //自己需要添加的方法 @end // ViewControllerEx.m @implementation ViewControllerEx // 方法的实现 @end |
1
2
3
4
5
6
7
8
9
|
// 这里有一个约定俗成的规定,类别文件命名时,是原类名+扩展标识名 // NSString+ex.h @interface NSString (ex) // 扩展的类回别方法 @end // NSString+ex.m @implementation NSString (ex) // 方法的实现 @end |
==========================================
一 、类目: 为已存在的类添加新的方法。但是不能添加实例变量。
应用:1、对现有的类进行扩展,如:系统中的类,在类目中增加的方法会被子类继承,而且在运行时跟其他的方法没有区别。
2、作为子类的替代方式,不需要定义和使用一个子类,可以通过类目直接向已有的类里增加方法。
3、对类中的方法进行归类,利用catigory把一个庞大的类划分为小块来分别进行开发,从而更好地对类中的方法进行更新和维护。
4、和普通接口有所区别的是,在Category的实现文件中的实例方法只要你不去调用它你可以不用实现所有声明的所有方法。
局限性: 1、无法向类目中添加新的实例变量。
2、类目中的方法具有更高的优先级,若在类目中覆盖原始类的方法(重载)。会引起super消息的无效,因此,一般不要覆盖现有类中的方法。
如果确实要重载,那就通过继承创建子类来实现。
命名方式:类名+扩展方法,如“UIAlertView+AFNetworking”。类目的接口声明与类的定义十分相似,但类目不继承父类,只需要带有一个括号,表明该类目的主要用 途。
在AFNetworking中有这样一个类目、实现附带alterview 的网络请求。
例:UIAlertView+AFNetworking.h文件中
<span style="font-family:System;font-size:12px;">#import <Foundation/Foundation.h>@interface UIAlertView (AFNetworking)+ (void)showAlertViewForTaskWithErrorOnCompletion:(NSURLSessionTask *)task delegate:(id)delegate;</span>
UIAlertView+AFNetworking.m文件中
<span style="font-family:System;font-size:12px;">#import "UIAlertView+AFNetworking.h"@implementation UIAlertView (AFNetworking)+ (void)showAlertViewForTaskWithErrorOnCompletion:(NSURLSessionTask *)task delegate:(id)delegate{ [self showAlertViewForTaskWithErrorOnCompletion:task delegate:delegate cancelButtonTitle:NSLocalizedStringFromTable(@"Dismiss", @"AFNetworking", @"UIAlertView Cancel Button Title") otherButtonTitles:nil, nil];}</span><span style="font-size:12px;font-family: 宋体, ‘Arial Narrow‘, arial, serif;"></span>
二、延展:延展的作用就是定义自己的私有方法。
形式和类目相同,不用新创建文件,延展中定义的方法在类本身的@implementation代码区域中进行实现。
当在定义延展的时候不提供类目名时,延展中定义的方法既被视为“必须实现”的API在这种情况下,如果方法没有实现代码,那么编译器会报警告,这个时候方法的实现就一定要出现在类主体的@implementation代码块中了。
==========================================
我们都知道objective C不能像C++一样支持多继承,但是在OC的使用经常会碰到需要使用多继承的情况。例如,ClassA中有methodA,ClassB中methodB,而现在需要使用这两个类中的方法。如何按照C++的编程思路,毫无疑问采用多继承就搞定了,在OC就需要动动脑子了。
其实我们在学习设计模式的时候知道,多继承的效率不高,而且采用组合的模式可以完全代替继承模式。那么,这种思路完全可以用在OC中实现多继承(或许OC抛弃多继承,就是强迫我们使用更高效的组合设计模式吧!)。下面用实际的代码来表示组合如何来代替多继承。
现在ClassC需要继承ClassA中methodA、ClassB中methodB,具体的代码实现为:
//定义ClassA以及其methodA
@interface ClassA : NSObject
{
}
-(void)methodA;
@end
//定义ClassB以及其methodB
@interface
ClassB : NSObject
{
}
-(void)methodB;
@end
//定义ClassC以及其需要的methodA,methodB
@interface
ClassC : NSObject {
ClassA *a;
ClassB
*b;
}
-(id)initWithA:(ClassA *)A b:(ClassB
*)B;
-(void)methodA;
-(void)methodB;
@end
//注意在ClassC的实现
@implementation ClassC
-(id)initWithA:(ClassA *)A b:(ClassB *)B{
a=[[ClassA alloc] initWithClassA: A];//[A copy];
b=[[ClassB alloc] initWithClassB: B];//[B copy];
}
-(void)methodA{
[a methodA];
}
-(void)methodB{
[b methodB];
}
上面是采用组合的方式实现了多继承的功能,解决了OC不能多继承的语法。那么还有其他的方式来实现多继承吗?
虽然OC在语法上禁止类使用多继承,但是在协议的遵守上却允许使用多继承。所以可以用协议来实现多继承。但是协议只能提供接口,而没有提供实现方式,如果只是想多继承基类的接口,那么遵守多协议无疑是最好的方法,而既需要多继承接口,又要多继承其实现,那么协议是无能为力了。多协议遵守比较简单,具体的实现方式这里就不讲了!
标签:
object-c下的多继承it |
分类: object-C |
我们知道object-C是在C语言的基础上添加了面向对象功能,相比于同样是对C语言进行扩展的C++,object-C更加简单,也更容易上手,但凡事必有利弊,作为编程语言,逻辑复杂也代表着其功能强大,例如C++中支持的多继承在我们object-C是不被支持的,那么object-C是否就真的抛弃多继承的逻辑设计了呢?答案是否定的,这里我们通过协议来实现类似C++中的多继承。
由上图,我们有类ClassA、ClassB、ClassC及类中分别有方法a{}、b{}、c{},我们希望通过类C继承A和B,C的对象就可以使用a、b、c方法了。例如:
ClassC
*cObject = [[ClassC alloc]
init];
[cObject a];
[cObject b];
[cObject c];
由于Objective-C在语法上禁止类使用多继承,所以我们ClassC无法直接继承ClassA和ClassB,但是在协议的遵守上却允许使用多继承。所以我们分享在ClassA和ClassB中定义协议,协议方法分别为a{}、b{},代码如下:
1、ClassA.h内容
@interface ClassA : NSObject
@end
@protocol ClassAProtocol <NSObject>
-(void)a;
@end
2、ClassB.h内容
@interface ClassB : NSObject
@end
@protocol ClassBProtocol <NSObject>
-(void)b;
@end
3、ClassC.h内容(引用ClassAProtocol和ClassBProtocol 协议)
而我在ClassC.m中的补充完善ClassAprotocol和ClassBProtocol中的a{}和b{}方法,详见下图
:
9月19日成都 OSC 源创会正在报名,送机械键盘和开源无码内裤
我们知道OC是不支持多重继承的,那么我们希望ClassA的某些子类在某种情况下又能调用ClassB中的方法该这么办呢,有人说使用Protocal啊,那么你会发现,当你想增加一个方法的调用时,还是需要到ClassA和ClassB中去维护两份代码。而且你必须要修改ClassA和ClassB去conform 你的protocal。
我们希望在不污染ClassA 和 ClassB的基础上使得ClassA的子类能够同时拥有ClassA和ClassB的方法(MethodA和MethodB),我认为category更适合这样的情景。
首先ClassA
1
2
3
4
5
6
7
8
9
10
11
12
|
@interface GTClassA : NSObject - ( void )methodA; @end @implementation GTClassA - ( void )methodA { NSLog(@ "this is methodA" ); } @end |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
@interface GTClassB : NSObject - ( void )methodB; @end @implementation GTClassB - ( void )methodB { NSLog(@ "this is methodB" ); } - ( void )dealloc { NSLog(@ "dealloc in %@" ,[self class ]); [super dealloc]; } @end |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
// Created by Guangtao Li on 13-11-10. // Copyright (c) 2013年 Guangtao Li. All rights
reserved. // #import "GTClassA.h" @interface GTClassA (ClassBInheritance) @end // Created by Guangtao Li on 13-11-10. // Copyright (c) 2013年 Guangtao Li. All rights
reserved. // #import "GTClassA+ClassBInheritance.h" #import "GTClassB.h" @implementation GTClassA (ClassBInheritance) -( void )forwardInvocation:(NSInvocation *)anInvocation{ if ([self respondsToSelector:[anInvocation
selector]]){ [anInvocation invokeWithTarget:self]; } else { GTClassB *classBInstance = [[GTClassB alloc]
init]; [anInvocation invokeWithTarget:classBInstance]; [classBInstance release]; //立刻释放了 } } -
(NSMethodSignature*)methodSignatureForSelector:(SEL)selector { NSMethodSignature* signature = [super
methodSignatureForSelector:selector]; if (!signature) { signature = [GTClassB
instanceMethodSignatureForSelector:selector]; } return signature; } -( BOOL )conformsToProtocol:(Protocol *)aProtocol{ if ([GTClassB conformsToProtocol:aProtocol] || [super
conformsToProtocol:aProtocol]){ return YES; } return NO; } |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
|
// GTClassA+ClassBInheritance.h // MultipleInheritanceTest // // Created by Guangtao Li on 13-11-10. // Copyright (c) 2013年 Guangtao Li. All rights
reserved. // #import "GTClassA.h" @ class GTClassB; @interface GTClassA (ClassBInheritance) @property (nonatomic,retain) GTClassB
*classBInstance; @end // // GTClassA+ClassBInheritance.m // MultipleInheritanceTest // // Created by Guangtao Li on 13-11-10. // Copyright (c) 2013年 Guangtao Li. All rights
reserved. // #import <objc/runtime.h> #import "GTClassA+ClassBInheritance.h" #import "GTClassB.h" static char const * const ClassBInstanceKey = "ClassBInstanceKey" ; @implementation GTClassA (ClassBInheritance) @dynamic classBInstance; -( void )forwardInvocation:(NSInvocation *)anInvocation{ if ([self respondsToSelector:[anInvocation
selector]]){ [anInvocation invokeWithTarget:self]; } else { if (self.classBInstance == nil) { self.classBInstance = [[GTClassB alloc] init]; [self.classBInstance release]; } [anInvocation
invokeWithTarget:self.classBInstance]; } } -
(NSMethodSignature*)methodSignatureForSelector:(SEL)selector { NSMethodSignature* signature = [super
methodSignatureForSelector:selector]; if (!signature) { signature = [GTClassB
instanceMethodSignatureForSelector:selector]; } return signature; } -( BOOL )conformsToProtocol:(Protocol *)aProtocol{ if ([GTClassB conformsToProtocol:aProtocol] || [super
conformsToProtocol:aProtocol]){ return YES; } return NO; } - (GTClassB *)classBInstance { return objc_getAssociatedObject(self,
ClassBInstanceKey); } - ( void )setClassBInstance:(GTClassB *)newClassBInstance
{ objc_setAssociatedObject(self, ClassBInstanceKey,
newClassBInstance, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } @end |
1
2
3
4
5
6
|
- ( void )dealloc { NSLog(@ "dealloc in %@" ,[self class ]); [self.classBInstance release]; [super dealloc]; } |
标签:
原文地址:http://www.cnblogs.com/dexjay/p/4781347.html