zoukankan      html  css  js  c++  java
  • objective-C中的扩展方法与partial class

     在c#中要扩展一个现有类非常easy,比方这样:
    ?
    1
    2
    3
    4
    5
    6
    7
    public static class Utils
    {
        public static void PrintToConsole(this string strSrc)
        {
            Console.WriteLine(strSrc);
        }  
    }
    这样就为String类加入了一个PrintToConsole的方法。用法例如以下:
    ?
    1
    2
    3
    4
    5
    6
    7
    class MainClass
    {
        public static void Main (string[] args)
        {
            "Hello World!".PrintToConsole();           
        }
    }
    在objective-C中,也有类似的处理办法:
    StringUtils.h 定义部分
    1. #import <Foundation/Foundation.h>  
    2.   
    3. @interface NSString(ExtNSString)   
    4.   
    5. -(void) PrintToConSole;  
    6.   
    7. @end  
    解释:@interface NSString(ExtNSString) 表示ExtNSString这个类将会扩展NSString,会为其添加一些通用的额外方法。
     
    StringUtils.m 实现部分
    1. #import "StringUtils.h"  
    2.   
    3. @implementation NSString(ExtNSString)   
    4.   
    5. -(void) PrintToConSole  
    6. {  
    7.     NSLog(@"%@",self);  
    8. }  
    9.   
    10. @end 
    用法例如以下:
    1. #import <Foundation/Foundation.h>  
    2. #import "StringUtils.h"  
    3.   
    4. int main (int argc, const charchar * argv[]) {  
    5.     NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];  
    6.   
    7.     NSString* str = @"Hello World!";  
    8.       
    9.     [str PrintToConSole];  
    10.       
    11.     [pool drain];  
    12.     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 (主要用于放一些成员变量。基本上仅仅是一个壳而已)
    1. #import <Foundation/Foundation.h>  
    2.   
    3. @interface BLL : NSObject {   
    4.     NSString* connStr;  
    5. }  
    6.   
    7. -(void) setConnString:(NSString*) connString;  
    8. -(NSString*) connString;  
    9.   
    10. @end 
    BLL.m实现
    1. #import "BLL.h"  
    2.   
    3. @implementation BLL  
    4.   
    5. -(void) setConnString:(NSString *)connString  
    6. {  
    7.     connStr = connString;  
    8. }  
    9.   
    10. -(NSString*) connString  
    11. {  
    12.     return connStr;  
    13. }  
    14.   
    15. -(void) dealloc  
    16. {  
    17.     [connStr release];  
    18.     [super dealloc];  
    19. }  
    20. @end  
    2、再定义Product.h用来扩展BLL类
    1. #import <Foundation/Foundation.h>  
    2. #import "BLL.h"  
    3.   
    4. @interface BLL(Product)  
    5.   
    6. -(void) addProduct: (NSString* )productName productNo:(NSString*)proNo;  
    7. -(void) deleteProduct:(NSString*) productNo;  
    8.   
    9. @end 
    Product.m
    1. #import "Product.h"  
    2. #import "BLL.h"  
    3.   
    4. @implementation BLL(Product)  
    5.   
    6. -(void) addProduct: (NSString* )productName productNo:(NSString*)proNo  
    7. {  
    8.     NSLog(@"connString=%@",connStr);//输出Bll.h中定义的成员connStr  
    9.     NSLog(@"addProduct success! productName:%@,productNo:%@",productName,proNo);  
    10. }  
    11.   
    12. -(void) deleteProduct:(NSString*) productNo  
    13. {  
    14.     NSLog(@"connString=%@",[self connString]);//也能够用属性来訪问  
    15.     NSLog(@"deleteProduct success! productNo:%@",productNo);  
    16. }  
    17. @end  

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

    1. #import <Foundation/Foundation.h>  
    2. #import "BLL.h"  
    3.   
    4. @interface BLL(Order)  
    5.   
    6. -(void) createOrder:(NSString*) productNo quantity:(int) amount;  
    7.   
    8. @end  

    Order.m

    1. #import "Order.h"  
    2.   
    3. @implementation BLL(Order)  
    4.   
    5. -(void) createOrder:(NSString*) productNo quantity:(int) amount  
    6. {  
    7.     NSLog(@"thank you for order our product. productNo:%@,quantity:%d",productNo,amount);  
    8. }  
    9.   
    10. @end   

    因为Product类与Order类都是扩展自BLL类。所以这三个类在逻辑上都是同一个类BLL,最后来看看怎样使用:

    1. #import <Foundation/Foundation.h>  
    2. #import "BLL.h"  
    3. #import "Product.h"  
    4. #import "Order.h"  
    5.   
    6. int main (int argc, const charchar * argv[]) {  
    7.     NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];  
    8.   
    9.     BLL *bll = [[BLL alloc] init];  
    10.     bll.connString = @"I am connection string.";  
    11.     [bll addProduct:@"iphone4" productNo:@"0001"];//调用Product.h中定义的方法  
    12.     [bll createOrder:@"0001" quantity:5];  //调用Order.h中定义的方法
    13.     [bll deleteProduct:@"0001"];
    14.     [bll release];        
    15.     [pool drain];  
    16.     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。

  • 相关阅读:
    深度优先和广度优先
    水管工游戏(深度优先)
    炸弹人
    广度优先(迷宫找人)
    System.Data.Entity.Core.MetadataException: 无法加载指定的无数据资源
    Element Cascader 级联选择器 单选操作优化
    Windows服务 ProjectInstaller 获取 路径
    Quartz.NET ScheduledFireTimeUtc 当超过1分钟时出现的问题。
    记录:一个SQL SERVER奇怪的问题。
    log4.net 配置
  • 原文地址:https://www.cnblogs.com/yangykaifa/p/6794670.html
Copyright © 2011-2022 走看看