@interface Shape : nsobject init{ Sha

iOS开发中怎样精辟易懂的解释 Delegate protocol interface这些概念?
iOS开发中怎样精辟易懂的解释 Delegate protocol interface这些概念
按时间排序
Delegate即为代理,也就是我自己的事情找代理做,我只负责method call,implementation交给代理Protocol 为协议,可以理解为是在代理时与代理沟通的协议,定义了函数。interface为接口,可以理解为当前类对于其他类可见的部分。如#include之后,其他类可以使用的变量及函数等等。如有不准确的地方敬请纠正。
中远海运Protocal:
运货合同位于大连的某钢铁厂生产了一批钢材,打算运往广州(协议中的方法),但不想自己买船运,于是发布了个合同广告(A声明属性 delegate),合同内容即协议(协议中的方法:把这批钢材从大连运往广州)。并不是所有的船公司都有运钢材的船,想接单必须具备能运钢材的船。中远海运立刻买了一条运钢材的船,具备了运货资质(B 声明对protocal实现,有能力处理协议中的方法)。于是,钢铁厂就跟中远签了合同(钢铁厂.delegate=中远海运),将运钢材的事情委托给了中远海运。
protocol就像一份jd老板:我们需要会xxxx的人候选人1:我会xxxx,还会yyyy候选人2:我会xxxx,还会zzzz
协议与委托 (Protocol and Delegate)1 协议:协议,类似于Java或C#语言中的接口,它限制了实现类必须拥有哪些方法。它是对对象行为的定义,也是对功能的规范。示例:// GoodChild.h
#import &Foundation/Foundation.h&
@protocol GoodChild &NSObject&
-(void)filialP
// Student.h
#import &Foundation/Foundation.h&
#import "GoodChild.h"
//注意实现协议的语法。
@interface Student : NSObject&GoodChild&
// Student.m
// protocol
// Created by sxt on 11-10-23.
// Copyright 2011年 __MyCompanyName__. All rights reserved.
#import "Student.h"
@implementation Student
- (id)init
self = [super init];
if (self) {
// Initialization code here.
return self;
-(void)filialPiety{
NSLog(@"孝敬父母。。");
此例中定义了一个协议GoodChild,类Student实现了此协议,所以必须有filialPiety方法。每个类虽只有一个父类,但可以实现多个协议,以逗号隔开便可。语法如下:@interface Student : NSObject&协议1,协议2&
2 委托:委托是objC中使用非常频繁的一种设计模式,它的实现与协议的使用是分不开的,让我们看一个综合示例:小公司老板日常的工作是管理公司、教导新员工、发工资与接电话。其中管理公司、教导新员工是老板要亲为的。而发工资与接电话老板希望招聘一个秘书来帮忙,于是对秘书的要求就是要略懂出纳发工资,要能帮助领导接电话。 而这两项要求便是协议,对类功能的限定。// SecProtocol.h
#import &Foundation/Foundation.h&
@protocol SecProtocol &NSObject&
-(void)payoff;
-(void)tel;
然后定义一个秘书类// Sec.h
#import &Foundation/Foundation.h&
#import "SecProtocol.h"
@interface Sec : NSObject&SecProtocol&
#import "Sec.h"
@implementation Sec
- (id)init
self = [super init];
if (self) {
// Initialization code here.
return self;
-(void)payoff{
NSLog(@"sec payoff");
-(void)tel{
NSLog(@"sec tel");
紧接着是老板类:// Boss.h
#import &Foundation/Foundation.h&
#import "SecProtocol.h"
@interface Boss : NSObject
//此属性用于指定秘书对象,此对象必须实现SecProtocol协议。
@property(nonatomic,retain) id&SecProtocol& detegate;
-(void)manage;
//教导新员工
-(void)teach;
#import "Boss.h"
@implementation Boss
@synthesize detegate=_detegate;
- (id)init
self = [super init];
if (self) {
// Initialization code here.
return self;
-(void)manage{
NSLog(@"boss manage");
-(void)teach{
NSLog(@"boss teach");
-(void)payoff{
NSAutoreleasePool *p=[[NSAutoreleasePool alloc] init];
[_detegate payoff];
[p release];
-(void)tel{
NSAutoreleasePool *p=[[NSAutoreleasePool alloc] init];
[_detegate tel];
[p release];
那么老板就具有这4个方法,当调用前2个时是自己完成功能,而调用后2个时则转为调用秘书的方法。此时我们跟秘书对象就叫做代理对象,代理模式的名字由来于此。最后调用测试下:// main.m
// delegate
// Created by sxt on 11-10-23.
// Copyright 2011年 Jinlong Wei. All rights reserved.
#import &Foundation/Foundation.h&
#import "Boss.h"
#import "Sec.h"
int main (int argc, const char * argv[])
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
//实例化老板对象
Boss *boss=[[[Boss alloc] init] autorelease];
//实例化秘书对象
Sec *sec=[[[Sec alloc] init] autorelease];
//设置老板的代理对象为秘书
boss.detegate=
//调用4个方法。
[boss payoff];
[boss tel];
[boss manage];
[boss teach];
[pool drain];
interface定义一个类。//Pen.h
#import &Foundation/Foundation.h&
//类名称为Pen , 继承自父类NSObject
@interface Pen : NSObject
//定义一个方法,无返回值,名称叫write
//减号表示是个实例方法 ,加号表示是个静态方法
#import "Pen.h"
@implementation Pen
//此方法为objC类的构造方法
- (id)init
self = [super init];
if (self) {
// Initialization code here.
//方法的实现,显示一行文字。
-(void)write{
NSLog(@"write....");
objC中每个类由2个文件组成,.h文件和.m文件。 这非常类似于C++的做法。当然,只有一个.h文件也可以写出一个完整的类。但通常我们将类的声明部分放在.h头文件中(interface),而将方法的实现写在.m文件中
我需要的数据,我自己自己不处理,委托给Delegate处理,为了避免所托非人,Delegate需要遵守一个咱们都能接受的Protocol。一个interface(class)只要声明自己遵守了某个我想要的&Protocol&,我就能把他信认为我的Delegate。
Delegate 委托给别人做 protocol 但是要限制受委托人的行为,就是protocolinterface Java的接口?
objectivec中@interface就是java中的class@protocol就是java中的接口interface接口/@protocol的鼻祖就是objectivec, java c#delphi也是和它学的@protocol和delegate是对应出现的它们有俩重要作用1.实现‘多继承’ 在可视化UI编程方面非常有用 用单继承结合接口方法覆盖通过组合实现类似多继承的效果2.解耦 可以复用方法无需了解类的细节 实现类似面向过程的低耦合编程(甚至可以说 @protocol表面是面向对象的 本质确是提供面向过程的实现 个人体会) 本身单继承结合接口 推崇的编程模式是少用继承多用组合 但是很多人不懂也不清楚。很多人不会用@protocol和delegate,特别是@protocol, 常陷于oo class的强耦合泥潭或者麻团,习惯或者乐于搞框架 代码量大了 oo多层继承后 不变成麻团几乎不可能。经常一个地方拉完屎再换个地方搞新的麻团或者屎 这个俗称跳槽 拉屎喜欢搞这个的人很多叫架构师或者高级工程师或者技术总监 他们喜欢在你需要一个香蕉的时候 给你一个拿着香蕉的大猩猩和后面整个森林 同时香蕉粘在大猩猩手上 你想扯也扯不开
如有错误之处还请指正1.Protocol(协议):一个协议是由一组(相关的)方法组成的,这组方法分为两类,acquired(必须实现的)和Optional(可选择实现的),一个类遵守某个协议,则相当于声明了一系列该协议中定义的方法。我觉得可以这么理解,若一个类遵守某个协议,则可以视为该类具有某种功能(例如一个类遵循UITableViewDataSource协议, 则可以视为该类具有向TableView提供数据源的功能)。而如果一个类定义了某个协议,则是该类希望别的类来替它实现的功能。2.Delegate(委托)Delegate是一种设计模式,目的是实现低耦合。委托和协议是有着紧密的联系的。通俗地讲,类A自己不具备某项功能,而委托类B来实现该项功能,代理类(类B)承担实际的功能。往往这种情况里,类A定义了协议和协议里的方法(即希望类B完成的功能),而类B遵守了该协议,实现具体的功能,完成代理的任务。成语“借刀杀人”也是Delegate模式的体现。3.Interface(接口)在iOS开发中,由@interface和相应的@end包围的部分用于描述类和类的方法。接口只定义类的成员,而不实现,这在面向对象编程里是很常见的概念,在iOS开发中也是一样的概念。
能否用一句浅显易懂的话说出protocol的精髓是一个分水岭。
理解好protocol,就能理解好代理了。protocol可对比常规的http协议、ssl协议等,本身是一种约定。常规的通信协议中,通信双方协定好协议格式,数据使用json还是xml?json格式是什么样的?该怎么解析?映射到Objective-C中,就是一个类或对象遵循什么协议就需要具备该协议约定的属性,实现该协议约定的方法。例如:一个类想要实现copy方法需要遵循NSCopying协议,实现协议中约定的“- (id)copyWithZone:(NSZone *)”方法。而代理则是一种用来解耦的模式,一个实例引用一个遵循某一协议的对象,无需知道该对象的具体类型,只需知道该对象遵循的协议。在适当位置给该对象发送协议约定的消息,进行某种操作。这就是代理。代理只能用于一对一的消息模型。Interface就是接口了,一个类可以有哪些可以对外(OC中无私有变量,无私有方法)使用的方法,一个实例可以接收哪些消息等。NSObject中methodSignatureForSelector、forwardInvocation两个消息方法 - 不积跬步 无以至千里 不积小流 无以成江海 - ITeye技术网站
博客分类:
在obj-c中我们可以向一个实例发送消息,相当于c/c++ java中的方法调用,只不过在这儿是说发送消息,实例收到消息后会进行一些处理。比如我们想调用一个方法,便向这个实例发送一个消息,实例收到消息后,如果能respondsToSelector,那么就会调用相应的方法。如果不能respond一般情况下会crash。今天要的,就是不让它crash。
首先说一下向一个实例发送一个消息后,系统是处理的流程:
1. 发送消息如:[self startwork]
2. 系统会check是否能response这个消息
3. 如果能response则调用相应方法,不能则抛出异常
在第二步中,系统是如何check实例是否能response消息呢?如果实例本身就有相应的response,那么就会相应之,如果没有系统就会发出methodSignatureForSelector消息,寻问它这个消息是否有效?有效就返回对应的方法地址之类的,无效则返回nil。如果是nil,Runtime则会发出-doesNotRecognizeSelector:消息,程序这时也就挂掉了. 如果不是nil接着发送forwardInvocation消息。
所以我们在重写methodSignatureForSelector的时候就人工让其返回有效实例。
我们定义了这样一个类
@interface TargetProxy : NSProxy {
id realObject1;
id realObject2;
- (id)initWithTarget1:(id)t1 target2:(id)t2;
@implementation TargetProxy
- (id)initWithTarget1:(id)t1 target2:(id)t2 {
realObject1 = [t1 retain];
realObject2 = [t2 retain];
- (void)dealloc {
[realObject1 release];
[realObject2 release];
[super dealloc];
// The compiler knows the types at the call site but unfortunately doesn't
// leave them around for us to use, so we must poke around and find the types
// so that the invocation can be initialized from the stack frame.
// Here, we ask the two real objects, realObject1 first, for their method
// signatures, since we'll be forwarding the message to one or the other
// of them in -forwardInvocation:.
If realObject1 returns a non-nil
// method signature, we use that, so in effect it has priority.
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector {
NSMethodSignature *
sig = [realObject1 methodSignatureForSelector:aSelector];
sig = [realObject2 methodSignatureForSelector:aSelector];
// Invoke the invocation on whichever real object had a signature for it.
- (void)forwardInvocation:(NSInvocation *)invocation {
id target = [realObject1 methodSignatureForSelector:[invocation selector]] ? realObject1 : realObject2;
[invocation invokeWithTarget:target];
// Override some of NSProxy's implementations to forward them...
- (BOOL)respondsToSelector:(SEL)aSelector {
if ([realObject1 respondsToSelector:aSelector]) return YES;
if ([realObject2 respondsToSelector:aSelector]) return YES;
return NO;
现在我们还用这个类,注意向它发送的消息:
id proxy = [[TargetProxy alloc] initWithTarget1:string target2:array];
// Note that we can't use appendFormat:, because vararg methods
// cannot be forwarded!
[proxy appendString:@"This "];
[proxy appendString:@"is "];
[proxy addObject:string];
[proxy appendString:@"a "];
[proxy appendString:@"test!"];
NSLog(@"count should be 1, it is: %d", [proxy count]);
if ([[proxy objectAtIndex:0] isEqualToString:@"This is a test!"]) {
NSLog(@"Appending successful.");
NSLog(@"Appending failed, got: '%@'", proxy);
运行的结果是:
count should be 1, it is:
Appending successful.
TargetProxy声明中是没有appendString与addObject消息的,在这儿却可以正常发送,不crash,原因就是发送消息的时候,如果原本类没有这个消息响应的时候,转向询问methodSignatureForSelector,接着在forwardInvocation将消息重定向。
///////////
下载次数: 0
浏览: 1577378 次
来自: China
缓存: /wend ...
/p/caedda ...
/swift-compa ...
/2015/09 ...
简单明了。7271人阅读
一. 基本概念
& &1. OC中没有命名空间机制,也没有包的概念,为了区分不同的类,在类名前加前缀
& & 2. OC中的关键字都以@开头,用于区分C和C++的关键字,字符串也以@开头,比如:
@interface Student : NSObject
NSLog(@&Hello World!&);
二. &面向对象
& &&1. @interface --------& 等于java中的class
& & &2. 类名后的冒号:---------& 等于java中的extends
& & &3. 函数前面的减号- &---------& 表示对象方法
& & & &函数前面的加号+ &---------& 表示类方法,等于java的static方法
& & &4. 函数的返回类型和参数的类型必须用括号,形参用冒号:表示
& & &以bean类的头文件示例:
@interface Student : NSObject{
}//成员变量的声明区间,成员变量必须在此声明
- (int)//本来是getAge,但是OC的习惯是用变量来命名get方法
- (void)setAge:(int)newA
//多形参的函数写法比较特别
- (void)setAge:(int)newAge andHeight:(int)newH
@end//类的结束标记,必须写
& & 对应的m文件为:
#import &Student.h&
@implementation Student
- (int)age{
- (void)setAge:(int)newAge{
age = newA
- (void)setAge:(int)newAge andHeight:(int)newHeight{
age = newA
height = newH
& & 5. 对象的创建和方法调用:
//OC创建对象分2步,先调用静态无参函数alloc申请内存,在调用静态无参函数init初始化
//1. Student *stu = [Student alloc];//仅仅为对象分陪内存空间
//2. stu = [stu init];//真正创建对象
//以上2步一般简写为:
Student *stu = [[Student alloc] init];
[stu setAge:100];
[stu setAge:100 andHeight:50];
NSLog(@&age is %i&,[stu age]);
[stu release];//对象使用完毕要释放内存
& &6. 对象的构造方法
@interface Student{
int _//标准写法
- (void)setAge:(int)
- (void)setNo:(int)
//构造方法
- (id)initWithAge:(int)age andNo:(int)
@end& & 对应的m文件:
#include &Student.h&
@implementation Student
- (int)age{
- (void)setAge:(int)age{
//实现构造方法
- (id)initWithAge:(int)age andNo:(int)no{
//以下写法不严谨
//self = [super init];
if(self=[super init]){
& & &7. @property简化set和get
& & & & 在头文件中这样声明:
@//编译器会自动补出其set和get方法& & & & 在m文件中这样实现:
@//编译器会自动生成set和get方法的实现
& & &8. 使用@class 提高编译效率,由于在h文件中,使用include的话,是将其内容全部拷贝过来,会影响编译效率,而且对应的h文件只有有任何改动,又要重新编译,为了解决这个问题,在h文件中,如果引用了另外一个对象,则使用@class O 代替include语法,用于告诉编译器该对象是存在的
@interface Student : NSObject
@property Book *
@end& & & & 但是在对应的m文件中,则必须要include入Book.h了.
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:104278次
积分:1127
积分:1127
排名:千里之外
原创:25篇
评论:27条
(2)(2)(1)(1)(1)(4)(4)(1)(1)(1)(1)(3)(5)Objective-c
面向对象画图形(此程序不符合内存管理规则) - 取啥名字? - ITeye技术网站
博客分类:
在同一个文件中,没有分割出来
#import &Foundation/Foundation.h&
// --------------------------------------------------
// constants for the different kinds of shapes and their colors
typedef enum {
kRedColor,
kGreenColor,
kBlueColor
// --------------------------------------------------
// Shape bounding rectangle
//声明结构用于形状边界
//为什么用结构来定义边界,因为结构可以方便的使用
//例:ShapeRect rect_0 = {0, 0, 1, 1};
typedef struct {
int x, y, width,
// --------------------------------------------------
// convert from the ShapeColor enum value to a human-readable name
NSString *colorName (ShapeColor color);
NSString *colorName (ShapeColor color)
switch (color) {
case kRedColor:
return @"red";
case kGreenColor:
return @"green";
case kBlueColor:
return @"blue";
return @"no clue";
} // colorName
// --------------------------------------------------
// All about Circles
@interface Circle : NSObject
ShapeColor
- (void) setFillColor: (ShapeColor) fillC
- (void) setBounds: (ShapeRect)
@end // Circle
@implementation Circle
- (void) setFillColor: (ShapeColor) c
fillColor =
} // setFillColor
- (void) setBounds: (ShapeRect) b
} // setBounds
- (void) draw
NSLog (@"drawing a circle at (%d %d %d %d) in %@",
bounds.x, bounds.y,
bounds.width, bounds.height,
colorName(fillColor));
@end // Circle
// --------------------------------------------------
// All about Rectangles
@interface Rectangle : NSObject
ShapeColor fillC
- (void) setFillColor: (ShapeColor) fillC
- (void) setBounds: (ShapeRect)
@end // Rectangle
@implementation Rectangle
- (void) setFillColor: (ShapeColor) c
fillColor =
} // setFillColor
- (void) setBounds: (ShapeRect) b
} // setBounds
- (void) draw
NSLog (@"drawing a rectangle at (%d %d %d %d) in %@",
bounds.x, bounds.y,
bounds.width, bounds.height,
colorName(fillColor));
@end // Rectangle
// --------------------------------------------------
// All about OblateSphereoids
@interface OblateSphereoid : NSObject
ShapeColor fillC
- (void) setFillColor: (ShapeColor) fillC
- (void) setBounds: (ShapeRect)
@end // OblateSphereoid
@implementation OblateSphereoid
- (void) setFillColor: (ShapeColor) c
fillColor =
} // setFillColor
- (void) setBounds: (ShapeRect) b
} // setBounds
- (void) draw
NSLog (@"drawing an egg at (%d %d %d %d) in %@",
bounds.x, bounds.y,
bounds.width, bounds.height,
colorName(fillColor));
@end // OblateSphereoid
// --------------------------------------------------
// Draw the shapes
void drawShapes (id shape, int count);
void drawShapes (id shape, int count) // 注意,这里和书上不同,上上为 id shapes[],但在xcode4.2中编译错误,抛Must explicitly describe intended ownership of an object array parameter
[shape draw];
} // drawShapes
// --------------------------------------------------
// The main function.
Make the shapes and draw them
int main (int argc, const char * argv[])
id shapes[3];
ShapeRect rect0 = { 0, 0, 10, 30 };
shapes[0] = [Circle new];
[shapes[0] setBounds: rect0];
[shapes[0] setFillColor: kRedColor];
drawShapes (shapes[0], 3);
ShapeRect rect1 = { 30, 40, 50, 60 };
shapes[1] = [Rectangle new];
[shapes[1] setBounds: rect1];
[shapes[1] setFillColor: kGreenColor];
drawShapes (shapes[1], 3);
ShapeRect rect2 = { 15, 19, 37, 29 };
shapes[2] = [OblateSphereoid new];
[shapes[2] setBounds: rect2];
[shapes[2] setFillColor: kBlueColor];
drawShapes (shapes[2], 3);
return (0);
hongmin118
浏览: 191379 次
来自: 常州
想转发一下,不知道怎么转发。评论一下吧。方便查看。
果然我这也是是防火墙问题
真强,居然有人把公司的面试题挂到javaeye上了
比如我要拦截不同业务的service类里面的方法下次自动登录
现在的位置:
& 综合 & 正文
iOS设计模式:工厂方法
原文地址:
1、什么是工厂方法
GOF是这样描述工厂模式的:
“Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory
Method lets a class defer instantiation to subclasses.”
在基类中定义创建对象的一个接口,让子类决定实例化哪个类。工厂方法让一个类的实例化延迟到子类中进行。
工厂方法要解决的问题是对象的创建时机,它提供了一种扩展的策略,很好地符合了开放封闭原则。工厂方法也叫做虚构造器(Virtual Constructor)。
如下图所示,是工厂方法的类结构图:
2、什么时候使用工厂方法
当是如下情况是,可以使用工厂方法:一个类不知道它所必须创建的对象的类时,一个类希望有它的子类决定所创建的对象时。
更多关于工厂方法的介绍,可以参考本文最后给出的参考内容。下面我们就来看看在iOS中工厂方法的一种实现方法。
iOS中工厂方法的实现
如下有一个类图,该图描述了下面即将实现的工厂方法(利用工厂方法,创建出不同的形状)。其中BVShapeFactory为工厂方法的基类,BVShape为形状的基类,BVClient通过BVShapeFactory,利用 BVShapeFactory的子类(BVCircleShapeFactory和BVSquareShapeFactory)分别创建出BVCircleShape和BVSquareShape。
如下图,是在Xcode中创建的相关文件
1.创建一个形状基类BVShape。该类中定义了形状的基本行为和属性,如下所示:
FactoryMethodPattern
Created by BeyondVincent on 13-5-15.
Copyright (c) 2013年 BeyondVincent. All rights reserved.
#define BV_Exception_Format @"在%@的子类中必须override:%@方法"
@interface BVShape : NSObject
@property (nonatomic, weak)NSString *
// 子类必须重写这个draw方法,否则会抛出异常错误
#import "BVShape.h"
@implementation BVShape
self = [super init];
if (self) {
// 做一些初始化任务
-(void)draw
// 如果是通过BVShape的实例调用此处的draw,则绘制一个BVShape图形
if ([self isMemberOfClass:[BVShape class]]) {
NSLog(@"绘制一个BVShape图形");
// 如果是通过BVShape子类的实例调用了此处的draw,则抛出一个异常:表明子类并没有重写draw方法。
// 注:在OC中并没有abstract class的概念,只有protocol,如果在基类中只定义接口(没有具体方法的实现),
则可以使用protocol,这样会更方便。
[NSException raise:NSInternalInconsistencyException
format:BV_Exception_Format, [NSString stringWithUTF8String:object_getClassName(self)], NSStringFromSelector(_cmd)];
在上面的代码中定义了一个draw方法,为了让子类必须实现该方法,在BVShape中做了特殊处理,具体内容可以看上面的代码,已经有注视了。
2.子类化形状基类。首先子类化一个圆形类:BVCircleShape。
#import "BVShape.h"
@interface BVCircleShape : BVShape
#import "BVCircleShape.h"
@implementation BVCircleShape
-(void)draw
NSLog(@"绘制一个BVCircleShape图形");
在上面的子类中,重写了基类的draw方法。同样,我们再子类化一个正方形类,并重写draw方法,如下代码所示:
#import "BVShape.h"
@interface BVSquareShape : BVShape
#import "BVSquareShape.h"
@implementation BVSquareShape
-(void)draw
NSLog(@"绘制一个BVSquareShape图形");
3.创建一个工厂方法的基类BVShapeFactory
#import "BVShape.h"
@interface BVShapeFactory : NSObject
-(BVShape *) factoryM
#import "BVShapeFactory.h"
@implementation BVShapeFactory
-(BVShape *)factoryMethod
// 在此处,子类必须重写factoryMethod方法。当然,在工厂模式中,也可以在此处返回一个默认的Product。
// 如果是通过BVShapeFactory子类的实例调用了此处的factoryMethod,则抛出一个异常:表明子类并没有重写factoryMethod方法。
[NSException raise:NSInternalInconsistencyException
format:BV_Exception_Format, [NSString stringWithUTF8String:object_getClassName(self)], NSStringFromSelector(_cmd)];
// 下面这个return语句只是为了消除警告,实际上永远都不会执行到这里。
在上面的代码中,定义了一个factoryMethod,该类的子类必须实现该方法,通过实现该方法,返回一个具体的形状对象。下面来看看该类的子类化。
4.子类化工厂方法的基类。首先子类化一个圆形工厂方法BVCircleShapeFactory:
#import "BVShapeFactory.h"
#import "BVCircleShape.h"
@interface BVCircleShapeFactory : BVShapeFactory
@implementation BVCircleShapeFactory
-(BVShape *)factoryMethod
return [[BVCircleShape alloc] init];
如上代码所示,重写了factoryMethod,返回一个BVCircleShape实例。下面来看看另外一个子类BVSquareShapeFactory:
#import "BVShapeFactory.h"
#import "BVSquareShape.h"
@interface BVSquareShapeFactory : BVShapeFactory
#import "BVSquareShapeFactory.h"
@implementation BVSquareShapeFactory
-(BVShape *)factoryMethod
return [[BVSquareShape alloc] init];
该子类返回的是一个BVSquareShape实例。
5.工厂方法的使用。定义一个BVClient类,在该类中演示工厂方法的使用。代码如下:
@interface BVClient : NSObject
-(void)doS
#import "BVClient.h"
#import "BVShapeFactory.h"
#import "BVCircleShapeFactory.h"
#import "BVSquareShapeFactory.h"
#import "BVShape.h"
#import "BVCircleShape.h"
#import "BVSquareShape.h"
@implementation BVClient
-(void)doSomething
// 工厂方法的实例化
BVShapeFactory *circleShapefactory = [[BVCircleShapeFactory alloc] init];
BVShapeFactory *squareShapefactory = [[BVSquareShapeFactory alloc] init];
// 通过工厂方法实例化对应的形状
BVShape *circleShape = [circleShapefactory factoryMethod];
BVShape *squareShape = [squareShapefactory factoryMethod];
// 调用形状的方法
[circleShape draw];
[squareShape draw];
&&&&推荐文章:
【上篇】【下篇】}

我要回帖

更多关于 nsobject copy 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信