zoukankan      html  css  js  c++  java
  • iOS 多参数,参数名与多态

    多个参数的写法

    (方法的数据类型)函数名:(参数1数据类型)参数1的数值的名字 参数2的名字: (参数2数据类型) 参数2值的名字 …. ;

    举个例子,一个方法的定义:

    -(void) setKids: (NSString *)myOldestKidName secondKid: (NSString *) mySecondOldestKidName thirdKid: (NSString *) myThirdOldestKidName;

    实现这个函数的时候:

    -(void) setKids: (NSString *)myOldestKidName secondKid: (NSString *) mySecondOldestKidName thirdKid: (NSString *) myThirdOldestKidName

    {  

    大儿子 = myOldestKidName; 二儿子 = mySecondOldestKidName; 三儿子 = myThirdOldestKidName;

    }

    调用的时候:

    Kids *myKids = [[Kids alloc] init];

    [myKids setKids: @”张大力” secondKid: @”张二力” thirdKid: @”张小力”];

    一上内容为引用 ,引用地址tp://blog.163.com/long_wtf/blog/static/185553270201111910536/

    刚开始接触Objective-C的时候,会感觉这种函数声明和调用都有点怪,实际是受C和C++传统函数声明方式的影响,看会C++的函数声明

    void setKids(string *myOldestKidName , string *mySecondOldestKidName , string *myThirdOldestKidName);

    调用的时候:

    myKids.setKids("张大力","张二力","张小力");

    在C++里,以我们的观点这个函数的”函数名“是setKids,然后()内是参数类型和形参变量

    C++中有overload(重载)的概念,我们可以声明void setKid(int myOldestKidAge , string *mySecondOldestKidName , string *myThirdOldestKidName);

    编译器是如何识别这两函数呢,实际是对于编译器会将所有参数的类型加到函数名上,变成setKid_string_string_string 和setKid_int_string_string (这里忽略了this等隐藏参数)

    对于编译器我们的两个setKid原本就是不同的,重载只是对于我们而言。

    对于Objective-C中,许多人认为“Objective-C中参数表是这样的, 参数名:(数据类型)形参名。第一个参数的参数名就是函数名”,其实这种理解不太正确,对于Objetive-C的函数名应该是由所有参数名的组合的,如上例中函数名是setKid:secondKid:thirdKid: 有使用过@selector的同学,会知道我们使用@selector获得带三个参数的函数的sel类型(可以当函数标识符理解)需要这样用@selector(setKid:secondKid:thirdKid)。

    所以我的理解时函数名是setKid:secondKid:thirdKid: ,而setKid实际是第一个参数的参数名。

    这有一个问题是Objecitve-C为什么不像C++一样,直接使用形参的数据类型放到函数名里,而非要让我们给每一个形参定义一个参数名呢。这是因为重载的方法只在类的内部,在C++中如果让同一函数在子类父类的不同对象中执行相同函数名有不同的实现,重载是办不到的,我们需要加vitrual关键字,把它声明成虚函数,这就是多态。在Objetive-C中所有的函数均是具有多态特性的,都可在运行时动态执行调用,我们需要一种方式对于所有的同名函数,在不同的对象可以动态执行,这时候Objetive-C便选择了中缀表达方式。

    二、在Objective-C中如何实现多态

         在Objective-C中是通过一个叫做selector的选取器实现的。在Objective-C中,selector有两个意思, 当用在给对象的源码消息时,用来指方法的名字。它也指那个在源码编译后代替方法名的唯一的标识符。 编译后的选择器的类型是SEL有同样名字的方法、也有同样的选择器。你可以使用选择器来调用一个对象的方法。

         选取器有以下特点:

         * 所有同名的方法拥有同样的选取器

         * 所有的选取器都是不一样的

         (1) SEL和@selector

              选择器的类型是 SEL。@selector指示符用来引用选择器,返回类型是SEL。

              例如:

             SEL responseSEL;       

                    responseSEL = @selector(loadDataForTableView:);     

             可以通过字符串来得到选取器,例如:

                   responseSEL = NSSelectorFromString(@"loadDataForTableView:");

             也可以通过反向转换,得到方法名,例如:

                   NSString  *methodName = NSStringFromSelector(responseSEL);

         (2) 方法和选取器

             选取器确定的是方法名,而不是方法实现。这是多态性和动态绑定的基础,它使得向不同类对象发送相同的消息成为现实;否则,发送     消息和标准C中调用方法就没有区别,也就不可能支持多态性和动态绑定。

             另外,同一个类的同名类方法和实例方法拥有相同的选取器。

         (3) 方法返回值和@参数类型

             消息机制通过选取器找到方法的返回值类型和参数类型,因此,动态绑定(例:向id定义的对象发送消息)需要同名方法的实现拥有相     同返回值类型和相同的参数类型;否则,运行时可能出现找不到对应方法的错误。

             有一个例外,虽然同名灶方法和实例方法拥有相同的选取器,但是它们可以有不同的参数类型和返回值类型。

  • 相关阅读:
    Bootstrap导航组件
    Bootstrap输入框组
    Bootstrap按钮式下拉菜单
    Bootstrap按钮组
    Bootstrap下拉菜单
    Bootstrap 中的 aria-label 和 aria-labelledby
    js 在函数中遇到的this指向问题
    js中 clientWidth offsetWidth scrollWidth等区别
    小程序--授权封装
    小程序--分享功能
  • 原文地址:https://www.cnblogs.com/SnowStark/p/5614627.html
Copyright © 2011-2022 走看看