温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

第二讲、实例变量可见度、方法

发布时间:2020-07-22 21:29:51 来源:网络 阅读:466 作者:遥星梦 栏目:开发技术

一、实例变量可见度

    可见度         特点

    public          实例变量可以在类的外部和内部操作

    protected    实例变量只能在该类和其子类内操作     默认

    private        实例变量只能在该类内访问

    内部:相应类的@implementation@end之间


     @interface Person : NSObject

     {

         @public

         NSString*_name;

         @protected

         NSString*_gender;

         int_age; //年龄

         @private

         NSString*_age;

      }

    mian.m文件中使用

    Person * p = [[Person alloc] init];
    p->_name = @"zhangyixing";
    // p->_gender = @'m';  // 警告
    // p->_age = 18;       // 警告


   为什么不使用@public   暴露细节 不符合封装

      在其他文件访问@protected修饰的实例变量-----方法   

    提示:添加两个方法。

    赋值:通过方法传入参数,在类的内部实现实例变量赋值。

    取值:通过方法获取实例变量的值。


二、方法--方法类型、返回值类型、方法名、参数列表

       OC中的方法------类方法、实例方法

    同一个中,所有的类方法中不能出现重名 所有的实例方法中不能出现重名

    1、  类方法:只能类使用   [类名 类方法名]   

      在类方法中不能使用实例变量 调用类方法时没有创建对象

    声明-----Person.h

    + (void)sayHi;

    实现-----Person.m

    + (void)sayHi
    {
       NSLog(@"hi");
    }

    2、实例方法:只能对象使用   [对象 实例方法名]

       声明-----Person.h

    - (void)sayHello;  

    实现-----Person.m  

    - (void)sayHello
    {
       NSLog(@"hello");
    } 

   3、声明方法   (返回值类型)没有参数只写方法名

    (1)无返回值、无参数
     - (void)sleep;

     实现

     - (void)sleep
    {
        NSLog(@"sleep");
    }

     使用

     [p sleep];


    (2)无返回值、有参数

     语法--- :(参数类型)参数名  

     参数以:开头   ":"标识参数,不能省略。有冒号必须有参数

     ///// 一个参数      

    - (void)eat:(NSString *)food; 

    实现

    - (void)eat:(NSString *)food
    {
       NSLog(@"%@",food);
    
    }

    使用

    [p eat:@"beef"];


    ///// 两个参数

    - (void)setName:(NSString *)name age:(NSInteger)age;  // 赋值

    实现

    - (void)setName:(NSString *)name age:(NSInteger)age
    {
       _name = name;
       _age = age;    

       // name和age是方法的形参,接收从外部传入的值
    }

    使用

    [p setName:@"zhangyixing" age:18];

   (3) 有返回值、无参数
    - (NSString *)getName; // 取值

    实现

    - (NSString *)getName
    {
        return _name;
    }

    使用

    NSLog(@"name=%@",[p getName]);

    // 方法名使用驼峰命名法---方法名: setName:age: 

       首字母小写;第一个参数修饰符首字母大写;

       第二个首字母小写;都使用驼峰命名法

   

   4、方法使用----[person sayHi];

      在OC中没有”student调用sayHi“这种表述。

      在OC中使用消息发送机制:[receiver  message]。

      正确表述:给student对象发送sayHi消息。

       1)student接收到消息,即方法sayHi;

       2)student找到sayHi方法,并执行。


三、setter、getter

    1、简述

    在OC里,为实例变量赋值的方法称作setter(设置器)。

    读取实例变量值的方法称作getter(访问器)。

    我们之前写的那些赋值取值的方法都可以称作setter和getter。

     2、实例

     (1)设置_name实例变量的值
      // setter方法是实例方法,没有返回值,只有一个参数
      // 方法名 set + 实例变量名(忽略_,使用驼峰命名法)
      // 参数  跟操作的实例变量有关 类型跟操作的实例变量一致  实例变量名(忽略_)
      - (void)setName:(NSString *)name;
      实现

      - (void)setName:(NSString *)name
     {
        _name = name;

       // name是方法的形参,接收从外部传入的值  _name实例变量
     }

     (2)访问实例变量
      // getter是实例方法 没有参数 返回值类型与操作的实例变量保持一致
      // 方法名  实例变量名(忽略_)  切记:不要以get开头
      - (NSString *)name;

     实现

      - (NSString *)name
     {
        return _name;
     }

     (3)使用

      // 使用setter方法给Person对象的实例变量_name赋值
      [p setName:@"zhang"];
      // 使用getter方法读取实例变量的值
       NSLog(@"name = %@", [p name]);


       3、与实例变量的关系

    无论setter还是getter内部操作的是实例变量

    每个实例变量都需要一对setter和getter方法

        4、main.m文件中使用

     // 使用setter方法给Person对象的实例变量_name 和_age赋值
     [p setName:@"zhang"];
     [p setAge:23];
     // 使用getter方法读取实例变量的值
     NSLog(@"name = %@, age = %ld", [p name], [p age]);


四、自定义初始化方法

    -(id)init这个初始化方法只能给实例变量设置默认值,不灵活

    - (id)init
    {
        return self;
    }

    -(id)initWithName:自定义初始化法,根据需求定义初始化方法

    // 自定义初始化方法 初始化对象时给_name和_age赋值
    - (id)initWithname:(NSString *)name age:(NSInteger)age;

    实现

    - (id)initWithname:(NSString *)name age:(NSInteger)age
    {
       // 对象初始化时可以传入姓名和年龄   将传入的值赋值给实例变量
       _name = name;
       _age = age;
       return self;
     }


        main.m文件中使用

     Person * p3 = [[Person alloc] initWithname:@"zhangyixing" age:18];
     Person * p4 = [[Person alloc] initWithname:@"liyifeng" age:20];
     NSLog(@"name=%@",[p3 name]);
     [p4 setName:@"liminhao"];
     NSLog(@"name=%@",[p4 name]);


五、导入文件

 1、#import导入头件,即:导入头件中的内容到当前类。

    #import “”导入自定义类,自己创建的文件  从当前工程目录开始查询

    #import  <> 导入类库中的头文件,自己创建的文件  从当前工程目录开始查询

    功能类似C语言中的#include,但是可以避免头文件被重复导入。

    容易出现循环导入头文件问题。

 2、#include 和 #import的区别

    (1)include不能重复导入同一个文件
    (2)import可以重复导入同一个文件

 3、@class

    #import可能会造成循环导入头文件问题,需要使用@class解决

    @class的作用,告知编译器系统class后面的标识符可以作为一个类名使用;并没有导入这个类的内容

    使用@class可以解决循环导入头文件的问题。

    如果需要在类的接口部分使用其他类型:

    1)在.h文件中,使用@class声明需要使用的类型;

    2)在.m文件中,使用#import导入需要使用的类型


 实例

    创建Man、Woman、Child三个类并完成声明与实现部分

    新创建Family类

      Family.h文件 

    #import <Foundation/Foundation.h>

    // 使用@class“导入”文件

    @class Man;
    @class Woman;
    @class Child;

    @interface Family : NSObject

    // 定义实例变量

    {
        Man * _father;
        Woman * _mother;
        Child * _kid;
    }
    // 初始化方法设置father和mother
    - (id)initWithFather:(Man *)father mother:(Woman *)mother;
    // 声明setter、getter方法
    - (void)setFather:(Man *)father;
    - (Man *)father;
    - (void)setMother:(Woman *)mother;
    - (Woman *)mother;
    - (void)setKid:(Child *)kid;
    - (Child *)kid;
    // 声明一般方法
    - (void)introduce;


       Family.m文件

    #import "Family.h"
    导入文件
    #import "Man.h"
    #import "Woman.h"
    #import "Child.h"
    @implementation Family
    // 初始化方法设置father和mother
    - (id)initWithFather:(Man *)father mother:(Woman *)mother
    {
        _father = father;
        _mother = mother;
        return self;
    }
    // 实现setter、getter方法
    - (void)setFather:(Man *)father
    {
        _father = father;
    }
    - (Man *)father
    {
        return _father;
    }
    - (void)setMother:(Woman *)mother
    {
        _mother = mother;
    }    
    - (Woman *)mother
    {
        return _mother;
    }
    - (void)setKid:(Child *)kid
    {
        _kid = kid;
    }
    - (Child *)kid
    {
        return _kid;
    }
    // 实现一般方法
    - (void)introduce
    {
        NSLog(@"father:%@,mother:%ld,kid:%@", [_father name], [_mother age], [_kid gender]);
    }


      main.m文件

   #import <Foundation/Foundation.h>

    // 导入文件

    #import "Man.h"
    #import "Woman.h"
    #import "Child.h"
    #import "Family.h"


    Man * m = [[Man alloc] initWithName:@"zhangjiashuai"];
    Woman * w = [[Woman alloc] initWithName:@"zhangjiamei" age:18];

    Family * f = [[Family alloc] initWithFather:m mother:w];

    Child * c = [[Child alloc] initWithName:@"zhangyi" gender:@"m"]; 
    [f setKid:c];
    [f introduce];


六、总结

   1、实例变量有3种常见的可见度:@public、@protected、@private。

      @public违背了封装特性,面向对象开发中很少使用;

      @protected默认可见度,自己和子类中能使用—>访问实例变量;

      @private自己类中能使用—>访问实例变量。

   2、方法是OC的核心,采用消息机制:[receiver message]。

      “-”message由对象来调用;

      “+”message由类来调用。









向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI