zoukankan      html  css  js  c++  java
  • Objective-C--- 多态 、 协议

    1 编写交通工具程序

    1.1 问题

    本案例需要创建一个TRTransportation类,类中有一个方法叫print的方法,该方法默认输出 “显示交通工具信息”,这个类作为父类,派生出三个子类TRTaxi的士类、TRBus巴士类和TRBike 自行车类。TRTaxi的士类覆盖了父类的print方法,改成自己的输出,"交通工具为的士";TRBus巴士类覆盖了父类的print方法,改成自己的输出,"交通工具为巴士";TRBike 自行车类覆盖了父类的print方法,改成自己的输出,"交通工具为单车"。

    在主程序中,创建三个交通工具,使用多态输出交通工具信息。

    1.2 步骤

    实现此案例需要按照如下步骤进行。

    步骤一:定义TRTransportation类

    首先,在Day04工程中新添加TRTransportation.h文件,用于定义新的类TRTransportation。

    代码如下所示:

     
    1. #import <Foundation/Foundation.h>
    2. @interface TRTRansportation : NSObject
    3. -(void)print;
    4. @end

    在上述代码中,为TRTransportation类添加一个方法print,用于输出信息“显示交通工具信息”到控制台。

    然后,在类TRTransportation的实现部分,即在TRTransportation.m文件中,添加print方法的实现。

    代码如下所示:

     
    1. #import "TRTransportation.h"
    2. @implementation TRTRansportation
    3. -(void)print{
    4. NSLog(@"显示交通工具信息");
    5. }
    6. @end

    步骤二:定义TRTaxi类

    首先,在Day04工程中新添加TRTaxi.h文件,用于定义新的类TRTaxi。

    代码如下所示:

    1. #import "TRTransportation.h"
    2. @interface TRTaxi : TRTRansportation
    3. @end

    上述代码可以看出,TRTaxi类继承自父类TRTRansportation。TRTaxi类并没有声明自己的属性和方法。

    然后,在类TRTaxi的实现部分,即在TRTaxi.m文件中,重写由父类TRTRansportation继承的print方法。

    代码如下所示:

    1. #import "TRTaxi.h"
    2. @implementation TRTaxi
    3. -(void)print{
    4. NSLog(@"交通工具为的士");
    5. }
    6. @end

    步骤三:定义TRBus类

    首先,在Day04工程中新添加TRBus.h文件,用于定义新的类TRBus。

    代码如下所示:

    1. #import "TRTransportation.h"
    2. @interface TRBus : TRTRansportation
    3. @end

    上述代码可以看出,TRBus类继承自父类TRTRansportation。TRBus类并没有声明自己的属性和方法。

    然后,在类TRBus的实现部分,即在TRBus.m文件中,重写由父类TRTRansportation继承的print方法。

    代码如下所示:

    1. #import "TRBus.h"
    2. @implementation TRBus
    3. -(void)print{
    4. NSLog(@"交通工具为巴士");
    5. }
    6. @end

    步骤四:定义TRBike类

    首先,在Day04工程中新添加TRBike.h文件,用于定义新的类TRBike。

    代码如下所示:

    1. #import "TRTransportation.h"
    2. @interface TRBike : TRTRansportation
    3. @end

    上述代码可以看出,TRBike类继承自父类TRTRansportation。TRBike类并没有声明自己的属性和方法。

    然后,在类TRBike的实现部分,即在TRBike.m文件中,重写由父类TRTRansportation继承的print方法。

    代码如下所示:

    1. #import "TRBike.h"
    2. @implementation TRBike
    3. -(void)print{
    4. NSLog(@"交通工具为单车");
    5. }
    6. @end

    步骤五:在主程序中定义以上各类的对象

    代码如下所示:

    1. #import <Foundation/Foundation.h>
    2. #import "TRTransportation.h"
    3. #import "TRTaxi.h"
    4. #import "TRBus.h"
    5. #import "TRBike.h"
    6. int main(int argc, const char * argv[])
    7. {
    8. @autoreleasepool {
    9. // insert code here...
    10. TRTRansportation* tran = [[TRTRansportation alloc] init];
    11. [tran print];
    12. TRTRansportation* tran1 = [[TRBus alloc] init];
    13. [tran1 print];
    14. TRTRansportation* tran2 = [[TRTaxi alloc] init];
    15. [tran2 print];
    16. TRTRansportation* tran3 = [[TRBike alloc] init];
    17. [tran3 print];
    18. }
    19. return 0;
    20. }

    在上述代码中,以下代码:

    1. TRTRansportation* tran = [[TRTRansportation alloc] init];
    2. [tran print];

    定义了一个TRTRansportation类的对象tran,并向对象tran发送print消息,以在控制台上输出“显示交通工具信息”。

    在上述代码中,以下代码:

    1. TRTRansportation* tran1 = [[TRBus alloc] init];
    2. [tran1 print];

    定义了一个TRTRansportation类类型的指针tran1,用它指向TRBus类的对象,这是允许的。在多态的概念中,允许用父类的指针指向派生类的对象。但此时只能向该指针指向的派生类对象发送父类中已有的消息,派生类中自定义的父类中没有的消息不能被发送,同时发送的这个消息将调用派生类中重写的函数。如上述代码中,向指向派生类对象的父类指针tran1发送父类中已经定义的print消息,调用的是派生类中重写的函数,所以在控制台上输出“交通工具为巴士”。

    在上述代码中,以下代码:

    1. TRTRansportation* tran2 = [[TRTaxi alloc] init];
    2. [tran2 print];

    定义了一个TRTRansportation类类型的指针tran2,用它指向TRTaxi类的对象,向该指针tran2发送父类中已经定义的print消息,调用的是派生类中重写的函数,所以在控制台上输出“交通工具为的士”。

    在上述代码中,以下代码:

    1. TRTRansportation* tran3 = [[TRBike alloc] init];
    2. [tran3 print];

    定义了一个TRTRansportation类类型的指针tran3,用它指向TRBike类的对象,向该指针tran3发送父类中已经定义的print消息,调用的是派生类中重写的函数,所以在控制台上输出“交通工具为单车”。

    1.3 完整代码

    本案例中,类TRTransportation声明,即TRTransportation.h文件,完整代码如下所示:

    1. #import <Foundation/Foundation.h>
    2. @interface TRTRansportation : NSObject
    3. -(void)print;
    4. @end

    类TRTransportation实现,即TRTransportation.m文件,完整代码如下所示:

    1. #import "TRTransportation.h"
    2. @implementation TRTRansportation
    3. -(void)print{
    4. NSLog(@"显示交通工具信息");
    5. }
    6. @end

    本案例中,类TRTaxi声明,即TRTaxi.h文件,完整代码如下所示:

    1. #import "TRTransportation.h"
    2. @interface TRTaxi : TRTRansportation
    3. @end

    类TRTaxi实现,即TRTaxi.m文件,完整代码如下所示:

    1. #import "TRTaxi.h"
    2. @implementation TRTaxi
    3. -(void)print{
    4. NSLog(@"交通工具为的士");
    5. }
    6. @end

    本案例中,类TRBus声明,即TRBus.h文件,完整代码如下所示:

    1. #import "TRTransportation.h"
    2. @interface TRBus : TRTRansportation
    3. @end

    类TRBus实现,即TRBus.m文件,完整代码如下所示:

    1. #import "TRBus.h"
    2. @implementation TRBus
    3. -(void)print{
    4. NSLog(@"交通工具为巴士");
    5. }
    6. @end

    本案例中,类TRBike声明,即TRBike.h文件,完整代码如下所示:

    1. #import "TRTransportation.h"
    2. @interface TRBike : TRTRansportation
    3. @end

    类TRBike实现,即TRBike.m文件,完整代码如下所示:

    1. #import "TRBike.h"
    2. @implementation TRBike
    3. -(void)print{
    4. NSLog(@"交通工具为单车");
    5. }
    6. @end

    主程序,即main.m,完整代码如下所示:

    1. #import <Foundation/Foundation.h>
    2. #import "TRTransportation.h"
    3. #import "TRTaxi.h"
    4. #import "TRBus.h"
    5. #import "TRBike.h"
    6. int main(int argc, const char * argv[])
    7. {
    8. @autoreleasepool {
    9. // insert code here...
    10. TRTRansportation* tran = [[TRTRansportation alloc] init];
    11. [tran print];
    12. TRTRansportation* tran1 = [[TRBus alloc] init];
    13. [tran1 print];
    14. TRTRansportation* tran2 = [[TRTaxi alloc] init];
    15. [tran2 print];
    16. TRTRansportation* tran3 = [[TRBike alloc] init];
    17. [tran3 print];
    18. }
    19. return 0;
    20. }

    2 编写SuperMan类

    2.1 问题

    本案例需要定义两个协议,一个是TRPerson,它定义了一个方法job;另一个是TRFly,它定义了一个方法fly。创建一个SuperMan类,采用以上两个协议,使该类具有飞翔和工作的能力。

    2.2 步骤

    实现此案例需要按照如下步骤进行。

    步骤一:定义协议TRPerson

    首先,在Day04-2工程中新添加TRPerson.h文件,用于定义新的协议TRPerson。

    代码如下所示:

    1. #import <Foundation/Foundation.h>
    2. @protocol TRPerson <NSObject>
    3. -(void)job;
    4. @end

    在上述代码中,定义了一个协议TRPerson,在协议中有一个方法job的声明,表示采纳这个协议的类将具有工作的能力。该协议继承自NSObject。

    步骤二:定义协议TRFly

    首先,在Day04-2工程中新添加TRFly.h文件,用于定义新的协议TRFly。

    代码如下所示:

    1. #import <Foundation/Foundation.h>
    2. @protocol TRFly <NSObject>
    3. -(void)fly;
    4. @end

    在上述代码中,定义了一个协议TRFly,在协议中有一个方法fly的声明,表示采纳这个协议的类将具有飞翔的能力。该协议继承自NSObject。

    步骤三:定义SuperMan类

    首先,在Day04-2工程中新添加SuperMan.h文件,用于定义新的类SuperMan。

    代码如下所示:

    1. #import <Foundation/Foundation.h>
    2. #import "TRFly.h"
    3. #import "TRPerson.h"
    4. @interface SuperMan : NSObject<TRFly,TRPerson>
    5. @end

    上述代码可以看出,SuperMan类采纳了两个协议,一个是TRFly,另一个是TRPerson。SuperMan类并没有声明自己的属性和方法。

    然后,在类SuperMan的实现部分,即在SuperMan.m文件中,对采纳的两个协议中的方法进行实现。当一个类采纳了某个协议后,在类的实现部分必须写出协议中声明的方法的实现。

    代码如下所示:

    1. #import "SuperMan.h"
    2. @implementation SuperMan
    3. -(void)fly{
    4. NSLog(@"具有飞行的能力");
    5. }
    6. -(void)job{
    7. NSLog(@"具有了工作的能力");
    8. }
    9. @end

    步骤四:在主程序中使用SuperMan类

    代码如下所示:

    1. #import <Foundation/Foundation.h>
    2. #import "TRPerson.h"
    3. #import "TRFly.h"
    4. #import "SuperMan.h"
    5. int main(int argc, const char * argv[])
    6. {
    7. @autoreleasepool {
    8. // insert code here...
    9. id<TRFly,TRPerson> sMan = [[SuperMan alloc]init];
    10. [sMan fly];
    11. [sMan job];
    12. }
    13. return 0;
    14. }

    在上述代码中,以下代码:

    1. id<TRFly,TRPerson> sMan = [[SuperMan alloc]init];

    定义了一个id类型的指针sMan,并将指针sMan指向SuperMan类的对象。该id类型的指针由于进行了<TRFly,TRPerson>协议限定,所以指针只能调用SuperMan类中实现的TRFly协议和TRPerson协议声明的方法。

    在上述代码中,以下代码:

    1. [sMan fly];
    2. [sMan job];

    分别向id类型的指针发送fly消息和job消息,调用SuperMan类中的方法实现。

    2.3 完整代码

    本案例中,协议TRPerson声明,即TRPerson.h文件,完整代码如下所示:

    1. #import <Foundation/Foundation.h>
    2. @protocol TRPerson <NSObject>
    3. -(void)job;
    4. @end

    本案例中,协议TRFly声明,即TRFly.h文件,完整代码如下所示:

    1. #import <Foundation/Foundation.h>
    2. @protocol TRFly <NSObject>
    3. -(void)fly;
    4. @end

    本案例中,类SuperMan声明,即SuperMan.h文件,完整代码如下所示:

    1. #import <Foundation/Foundation.h>
    2. #import "TRFly.h"
    3. #import "TRPerson.h"
    4. @interface SuperMan : NSObject<TRFly,TRPerson>
    5. @end

    类SuperMan实现,即SuperMan.m文件,完整代码如下所示:

    1. #import "SuperMan.h"
    2. @implementation SuperMan
    3. -(void)fly{
    4. NSLog(@"具有飞行的能力");
    5. }
    6. -(void)job{
    7. NSLog(@"具有了工作的能力");
    8. }
    9. @end

    主程序,即main.m,完整代码如下所示:

    1. #import <Foundation/Foundation.h>
    2. #import "TRPerson.h"
    3. #import "TRFly.h"
    4. #import "SuperMan.h"
    5. int main(int argc, const char * argv[])
    6. {
    7. @autoreleasepool {
    8. // insert code here...
    9. id<TRFly,TRPerson> sMan = [[SuperMan alloc]init];
    10. [sMan fly];
    11. [sMan job];
    12. }
    13. return 0;
    14. }
  • 相关阅读:
    postman参数化—上个接口返回数据作为下个接口入参
    postman设置token为全局变量
    postman请求https协议接口
    安装VMware 置灰正确解决办法
    Cron 表达式详解
    Jmeter + ant + jenkins轻量级接口自动化测试
    Jmeter CSV 参数化/检查点/断言
    Android专项测试-cpu,流量
    Android专项测试-获取启动时间
    腾讯云测试工程师--面试总结
  • 原文地址:https://www.cnblogs.com/52190112cn/p/5049263.html
Copyright © 2011-2022 走看看