objective-C中的扩展方法与partial class

 在c#中要扩展一个现有类很容易,比如这样:

	public static class Utils
	{
		public static void PrintToConsole(this string strSrc)
		{
			Console.WriteLine(strSrc);
		}
	}

这样就为String类添加了一个PrintToConsole的方法,使用方法如下:

	class MainClass
	{
		public static void Main (string[] args)
		{
			"Hello World!".PrintToConsole();
		}
	}

在objective-C中,也有类似的处理办法:

StringUtils.h 定义部分

#import <Foundation/Foundation.h>

@interface NSString(ExtNSString) 

-(void) PrintToConSole;

@end

解释:@interface NSString(ExtNSString) 表示ExtNSString这个类将会扩展NSString,会为其增加一些通用的额外方法。

 

StringUtils.m 实现部分

#import "StringUtils.h"

@implementation NSString(ExtNSString) 

-(void) PrintToConSole
{
	NSLog(@"%@",self);
}

@end

使用方法如下:

#import <Foundation/Foundation.h>
#import "StringUtils.h"

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

	NSString* str = @"Hello World!";

	[str PrintToConSole];

    [pool drain];
    return 0;
}

不过有一点要特别注意:c#中如果开发人员增加的扩展方法跟.net框架自带的现有方法重名,实际运行时将以系统自带的现有方法为准。但在obj-C中,这种情况下开发人员新增加的重名方法会覆盖系统原有的方法,而且没有任何提示!一个好的习惯是为所有扩展方法(包括类名),都加一个特殊的前缀或后缀,以避免重名。

 

下一个话题:partial class

做过asp.net开发的程序员都知道,c#中的partial class可以方便的将同一个类的代码,分散在多个不同的物理文件中,编译器在编译时能自动将它们合并。这是一个很棒的功能,在团队开发中我经常把一个类的不同业务模块,分散成几个不同的物理文件(比如class_jimmy.cs,class_mike.cs...),然后jimmy只在class_jimmy.cs中写代码,mike只在class_mike.cs中写代码,在很大程度上这样可以减少(或避免)最终svn提交合并时的冲突。

表面上看,partial class与扩展方法是风马牛不相及的二个概念,但是在obj-C中,这二个其实是一回事。

场景:比如一个商城系统,对产品的增、删、改定义,我想单独放到文件Product.h中,而对订单的处理,我想单独放到文件Order.h中,但是这些跟业务相关的处理,我想在逻辑上把它们都归到同一个类BLL.h中。

看看obj-C中的做法:(主要是看几个文件是如何组织成一个类的,代码只是示例而已)

1、先定义BLL.h (主要用于放一些成员变量,基本上只是一个壳而已)

#import <Foundation/Foundation.h>

@interface BLL : NSObject {
	NSString* connStr;
}

-(void) setConnString:(NSString*) connString;
-(NSString*) connString;

@end

BLL.m实现

#import "BLL.h"

@implementation BLL

-(void) setConnString:(NSString *)connString
{
	connStr = connString;
}

-(NSString*) connString
{
	return connStr;
}

-(void) dealloc
{
	[connStr release];
	[super dealloc];
}
@end

2、再定义Product.h用来扩展BLL类

#import <Foundation/Foundation.h>
#import "BLL.h"

@interface BLL(Product)

-(void) addProduct: (NSString* )productName productNo:(NSString*)proNo;
-(void) deleteProduct:(NSString*) productNo;

@end

Product.m

#import "Product.h"
#import "BLL.h"

@implementation BLL(Product)

-(void) addProduct: (NSString* )productName productNo:(NSString*)proNo
{
	NSLog(@"connString=%@",connStr);//输出Bll.h中定义的成员connStr
	NSLog(@"addProduct success! productName:%@,productNo:%@",productName,proNo);
}

-(void) deleteProduct:(NSString*) productNo
{
	NSLog(@"connString=%@",[self connString]);//也可以用属性来访问
	NSLog(@"deleteProduct success! productNo:%@",productNo);
}
@end

3、定义Order.h继续扩展BLL类

#import <Foundation/Foundation.h>
#import "BLL.h"

@interface BLL(Order)

-(void) createOrder:(NSString*) productNo quantity:(int) amount;

@end

Order.m

#import "Order.h"

@implementation BLL(Order)

-(void) createOrder:(NSString*) productNo quantity:(int) amount
{
	NSLog(@"thank you for order our product. productNo:%@,quantity:%d",productNo,amount);
}

@end

由于Product类与Order类都是扩展自BLL类,所以这三个类在逻辑上都是同一个类BLL,最后来看看如何使用:

#import <Foundation/Foundation.h>
#import "BLL.h"
#import "Product.h"
#import "Order.h"

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

	BLL *bll = [[BLL alloc] init];
	bll.connString = @"I am connection string.";
	[bll addProduct:@"iphone4" productNo:@"0001"];//调用Product.h中定义的方法
	[bll createOrder:@"0001" quantity:5];
	[bll deleteProduct:@"0001"];//调用Order.h中定义的方法
	[bll release];
    [pool drain];
    return 0;
}

运行结果:

2011-02-26 22:29:30.369 Demo[1292:a0f] connString=I am connection string.
2011-02-26 22:29:30.376 Demo[1292:a0f] addProduct success! productName:iphone4,productNo:0001
2011-02-26 22:29:30.378 Demo[1292:a0f] thank you for order our product. productNo:0001,quantity:5
2011-02-26 22:29:30.379 Demo[1292:a0f] connString=I am connection string.
2011-02-26 22:29:30.380 Demo[1292:a0f] deleteProduct success! productNo:0001

皆大欢喜,很多语言和技术真是“一门通,处处通”,也许:c#中的"扩展方法"与"部分类"的设计灵感正是来自objective-C。

时间: 2024-09-29 21:34:52

objective-C中的扩展方法与partial class的相关文章

C#3.0 中使用扩展方法来扩展接口

有关扩展方法的一些知识点请参看我的前篇博客:C#3.0 中的扩展方法 (Extension Methods)前篇博客中我重点介绍了两个特殊场景:1.扩展方法跟原来类的方法重名时候的处理逻辑2.扩展方法的嵌套现在我们来看扩展方法使用的第三个场景:使用扩展方法来扩展接口 应用场景举例:我们有时候会发现最初定义的一个接口,在现在环境下,这个接口需要再增加一个函数.有了扩展方法后,我们在这种情况下又多了一种实现的选择.下面以代码来说明这个问题:namespace Hongjun.Guo{interfac

.net3.0中的扩展方法(示例)

先定义一个类Utils,在该类中定义了一个string类的扩展方法_IsNull  using System;namespace LinqDemo.App_Code{    public static class Utils    {        /**//// <summary>        /// 传统写法        /// </summary>        /// <param name="s"></param>     

说说NET3.5中的扩展方法

扩展方法配合Lambda表示达,可以方便我们进行数据的查询,看个代码吧: IEnumerable<string> x=new List<string> {"1","zzl","good"}; //为对象赋值 foreach (var info in x.ForUser("zzl")) //从其中筛选zzl这个字符 { Response.Write(info); }   public static cla

asp.net中 C#扩展方法实例

这是msdn上说的,也就是你可以对String,Int,DataRow,DataTable等这些类型的基础上增加一个或多个方法,使用时不需要去修改或编译类型本身的代码. 先做个例子吧,以String为例,需要在字符串类型中加一个从字符串转为数值的功能. 以往我们可能是这样做的,会专门写一个方法做过转换 public static int StrToInt(string s) {     int id;     int.TryParse(s, out id);//这里当转换失败时返回的id为0  

C#中使用扩展方法对调用进行验证

利用C# 3.0提供的扩展方法技术,可以为已经编译好的程序集类型增加新的方法,从而应对新的扩展.除了在可扩展性方面所具有的优势之外,如果能够合理地结合泛型与类型推断,扩展方法还可以有效降低代码的重复,提高程序的可重用性.例如,这样的方法实现: public class CustomerDAL { public IEnumerable<Customer> FindCustomers(string roleName) { return from customer in context.Custom

asp.net中CSharpThinking 扩展方法

本章主要描述扩展方法的应用及相关原理. 一, 演变 1.1 扩展方法特征 1)必须在一个静态方法中. 2)至少有一个参数. 3)第一个参数必须附加this关键字作为前缀. 4)第一个参数不能有其他任何修饰符(如 out,ref). 5)第一个参数的类型不能是指针. 6) 如果扩展方法名称与类型的方法一样(如都命名为ToString),则只有类型的方法会被调用,而扩展方法的不会,这是一个优先级问题. 1.2 扩展方法与普通静态方法的比较   C#2 时对一个类进行扩展而又不能应用继承方式时,只能编

.Net 2.0中使用扩展方法

大家都知道扩展方法是不能直接在2.0中使用的需要引用一个‍System.Core的dll不过现在有更加简单的方法了只要在工程项目中加入以下代码就OK啦‍namespace System.Runtime.CompilerServices{    [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class | AttributeTargets.Assembly)]    public sealed class ExtensionA

C# 3.0语言新特性(语言规范):2 扩展方法

规范 原文:<C# Version 3.0 Specification>,Microsoft翻译:lover_P 扩展方法(Extension Methods)是一种静态方法,可以通过实例方法的语法进行调用.从最终效果上看,扩展方法使得扩展一个现有类型和构造一个具有附加方法的类型变成了现实. 注意 扩展方法很难发觉,并且比起实例方法在功能性上有很大限制.出于这些原因,我们建议保守地使用扩展方法,仅在实例方法不大可行或根本不可行的时候才使用. 扩展成员的其他类型,如属性.事件和运算符都在考虑之中

Infosphere Datastage的扩展方法应用实践

我们知道, Infosphere Datastage 是一个功能强大的数据抽取.转换.装载工具,广泛用于用户信息整合项目之中.它不仅提供了丰富的数据接口,可以连接种类广泛的大型机.数据库.ERP/CRM 等企业应用及外部信息资源,它还提供了几十个数据转换 stage 及上百个数据转换函数,可以满足我们数据转换的需求,其中,比较常用的 Stage 主要包括: 用于数据源及目标的 stage:各种数据库的 connector.sequential file.data set 用于数据合并的 stag