zoukankan      html  css  js  c++  java
  • objectiveC中的扩展方法与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。

    作者:菩提树下的杨过
    出处:http://yjmyzz.cnblogs.com
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    AE开发 入门教程
    工作空间工厂 打开文件例子
    Delphi IDE使用的一些主要技巧
    动画演示 Delphi 2007 IDE 功能[2]
    Delphi的类与继承
    属性的自动完成
    DELPHI中函数、过程变量的声明与应用
    Delphi回车键切换焦点
    delphi 窗体的创建和释放
    delphi assigned函数的用法
  • 原文地址:https://www.cnblogs.com/yjmyzz/p/1965968.html
Copyright © 2011-2022 走看看