• OC面向对象-多态


    OC面向对象-多态

    一、基本概念

      

      1>多态在代码中的体现,即为多种形态,没有继承就没有多态

      2>在使用多态时,会进行动态检测,以调用真实的对象方法

      3>多态在代码中的体现即父类指针指向子类对象

      Animal类的声明

    #import <Foundation/Foundation>
    //声明一个Animal类,该类继承自NSObject
    @interface Animal : NSObject
    //在Animal类中声明一个eat的对象方法
    -(void) eat;
    @end

      Animal类的实现

    #import "Animal.h"
    /**eat方法的实现*/
    @implementation Animal
    -(void) eat{ NSLog(@"动物吃东西"); } @end

      Dog继承自Animal类

    #import "Animal.h"
    /**Dog类继承自Animal类,拥有了Animal类的所有属性跟方法*/
    @interface Dog : Animal
    //在子类中声明了父类中已经有的eat方法,这称之为方法的重写
    -(void) eat;
    @end

      Dog类的实现

    #import "Dog.h"
    @implementation Dog
    /** 重写eat*/
    -(void) eat{
        NSLog(@"狗吃东西");
    }
    @end

      测试程序

    #import <Foundation/Foundation>
    #import "Animal.h"
    #import "Dog.h"
    
    int main(){
    
        //Dog类型的指针指向Dog类型的对象
        Dog * dog=[[Dog alloc] init];
        
        .//Dog类对象调用对象方法
        [dog eat];
        
        //多态
        //父类指针指向子类对象
        Animal * a=[[Dog alloc] init];
        //这里调用的是Dog类中的eat方法
        [a eat];
        
        //Animal类型的指针指向Animal类型的对象
        Animal * a1=[[Animal alloc] init];
        [a1 eat];
        
        //下面都是多态的体现
        NSObject *n=[[Dog alloc] init];
        //[n eat] //不能这样调用
        NSObject * n1=[[Animal alloc] init];
        
    return 0;
    }

    二、使用注意

      代码分析

        Dog *dog=[[Animal alloc] init];  动物是一条狗?语义正确吗?

        NSString *str=[Dog new];   狗是一个字符串?正确吗?

      OC语言是一门弱语言,编译的时候并不会报错,所以这就要求我们在实际的开发过程中一定要按照既定的规范来写代码,不要出现狗是一个字符串的问题.

      多提的好处:

        需要一个新的函数专门用来喂狗

        void feed(Dog *d){

          [d eat];

    } 

        如果这个时候也需要喂猫,那就应该重写一个新的函数

        void feed(Cat *c){

          [c eat];

    } 

        而狗和猫实际上都继承自动物这个类,在这里就可以使用多态来简化代码了,这里只需要把函数的参数写成是Animal *类型的,那么Dog和Cat类型的对象就都可以传入进来,调用的时候直接改变参数就可以了.

      多态的局限性:

        父类类型的指针变量不能直接调用子类特有的方法.

        不建议的做法:

        Animal *a=[[Dog alloc] init];

        [a run];//在Animal类中没有run方法,这里调用了狗对象的方法。

        解决方法:可以将a强制转换为Dog*类型的变量,如下:

        Dog *d=(Dog *)a;//使用强制转换,这里a和d指向的是同一个狗对象

    三、多态使用总结

      1>没有继承就么有多态

      2>代码的体现:父类类型的指针指向子类对象

      3>好处:如果函数方法参数中使用的是父类类型,则可以传入父类和子类对象,而不用再去定义多个函数来和相应的类进行匹配了

      4>局限性:父类类型的变量不恩给你直接调用子类特有的方法,如果必须要调用,则必须强制转换为子类特有的方法

    四、字符串补充内容

      @"123'字符串也是一个对象,属于NSString这个类,下面对字符串对象的一些代码说明:

    #import <Foundation/Foundation>
    int main(){
    
        //最简单的创建字符串的方式
        NSString *str=@"张三";
        char *name="张三";
        
        //打印字符串
        NSLog(@"%s",name);
        NSLog(@"%@在看书",str);
        
        int a=5;
        int b=10;
        //创建字符串的另一种方法
        NSString *str=[NSString stringWithFormat:@"我已经敲了%d个小时,准备学够%d个小时",a,b];
        NSLog(@"%@",str);
        return 0;
    }

      字符串对象的length方法:计算的是字符串的字数,而不是像strlen函数那样,计算的是字符数.如:"哈ha123"length得出的结果是6,返回unsigned long类型,而strlen函数得出的结果是8,因为一个汉字占3个字节.

      提示:字数也包括空格

        用途:给符号名称指定程序常量,放在程序的开始,但是要在#import的后面

          注意:定义的常量最好都要大写

  • 相关阅读:
    writeToFile 读写文件问题
    iOS 设置代理过程
    iOS UIView 快速修改 frame,
    touches,motion触摸事件响应
    集合视图控制器(CollectionViewController) 、 标签控制器(TabBarController) 、 高级控件介绍
    触控(Touch) 、 布局(Layout)
    Autoresizing和AutoLayout
    动画(Animation) 、 高级动画(Core Animation)
    ios开发环境 分支语句 、 循环结构(for) 、 循环结构
    oc内存管理总结(一)
  • 原文地址:https://www.cnblogs.com/my-garden/p/5428982.html
Copyright © 2020-2023  润新知