• OC:方法


    三种可见度

    1.@public  

    被public 修饰的变量可以在外部(再声明一个新的类,也能访问) 和 该类的内部(在该类的.m文件内部)被访问,这样就可以在 main 函数中访问

    @public 一般是不安全的 凡是被@public 修饰的在外部都会被访问 暴露内部写的细节(内部代码的实现)有违背面向对象封装的思想(外部可访问、可修改),所以一般不用这种

    2.@ protected

    受保护的,只能在该类 和他的子类中可以访问(如在人类的下面的学生类)是实例变量默认的可见度

    3.@private

    私有的可见度 只能在该类的内部访问(子类也使用不了) 违背了继承的思想

     NSObject  类是根类 是基类

    总结: 三种可见度(及其区分),为了保护实例对象的封装性,我们有了setter getter 设置器,区分 self 究竟在不同的场景中代表什么?

    #import <Foundation/Foundation.h>
    #import "Person.h"
    
    int main(int argc, const char * argv[]) {
        @autoreleasepool {
            // insert code here...
            NSLog(@"Hello, World!");
            //今天的学习内容是:方法 与 可见度
            //三大特性:封装 继承 多态
            Person *per = [[Person alloc]init];
    //        per ->_name = @"张俊伟";//前面可见度改为默认的了
    //        per ->_age = 45;
    //        per ->_gender = @"男";
    //        per ->_heigth = 1.75;
    //        per ->_weight = 125;
            [per setName:@"ann"];
            NSString * name = [per getName];
            NSLog(@"name is %@",name);
            [per setAge:45];//赋值
            [per age];//取值
            NSLog(@"%ld",[per age]);
            [Person methoodForTest];
            [per objectMethood];
            [per class];//这里返回的就是 per 指向的类
        }
        return 0;
    }
     main
    #import <Foundation/Foundation.h>
    
    @interface Person : NSObject
    {
        //@public//被public 修饰的变量可以在外部(再声明一个新的类,也能访问) 和 该类的内部(在该类的.m文件内部)被访问,这样就可以在 main 函数中访问
        // @ protected 受保护的,只能在该类 和他的子类中可以访问(如在人类的下面的学生类)是实例变量默认的可见度
        // @private 私有的可见度 只能在该类的内部访问(子类也使用不了) 违背了继承的思想
        // NSObject  类是根类 是基类
        //@public 一般是不安全的 凡是被@public 修饰的在外部都会被访问 暴露内部写的细节(内部代码的实现)有违背面向对象封装的思想,所以一般不用这种
        NSString *_name;
    //    NSString *_address;
        @protected
        NSInteger _age;
        CGFloat   _heigth;
        @private
        NSString *_gender;
        CGFloat   _weight;
    }
    //为 _name 去赋值 (外面不能访问到 _name 添加一个方法,让外部能够访问)
    - (void)setName:(NSString *)name; //设置器 setter方法
    // 获取 _name 的值 (取值) //访问器  getter方法
    - (NSString *)getName; //规范化写法:getName 改为 name 方法名 就是 实例变量名 那个下划线可以省略
    /*
     正是因为我们的可见度是默认的受保护的状态 protected,这样的话我们在外部就无法通过指向操作符去访问到她的实例变量,访问的过程就是取值 赋值 的过程。
     所以我们就为它添加了两个方法,为实例变量去赋值、取值
     设置器:setter 方法  命名规范:set + 实例变量名(首字母大写)
     访问器:getter 方法  命名规则:get + 实例变量名 (或者更为规范的方法 就是直接给出实例变量名)
     ( 如果实例变量的名字以下划线 _ 开头一般就是省去 _ )
     通过 setter 方法为实例变量进行赋值操作
     通过 getter 方法来获取实例变量的值
     */
    
    //为 _age 去赋值
    - (void)setAge:(NSInteger)age;
    //获取 _age 的值
    - (NSInteger)age;
    //为 _gender 赋值
    - (void)setGender:(NSString *)gender;
    //获取 _gender 的值
    - (NSString *)gender;
    //为 _height 赋值
    //- (void)setHeight:()
    //获取 _height 的值
    
    //为 _weight 赋值
    
    //获取 _weight 的值
    
    /*
     oc 中的方法分为两种 
     (1)类方法  
     (2)(对象方法)实例方法
     + 对应的是类方法
     - 对应的是实例方法 也是对象方法
     */
    //声明一个类方法 + 开头
    + (void)methoodForTest;
    + (void)classMethood;
    //声明对象方法,就是用 - 开头
    - (void)objectMethood;
    //一次性为全部的实例变量赋值
    - (void)setNameOnce:(NSString *)name
                    age:(NSInteger)age
                 gender:(NSString *)gender
                 height:(CGFloat)height
                 weight:(CGFloat)weight;
    @end
     person.h 
    #import "Person.h"
    
    @implementation Person
    //为 _name 去赋值 (外面不能访问到 _name 添加一个方法,让外部能够访问)
    - (void)setName:(NSString *)name{
        _name = name;//将外部的变量赋值给实例变量名
    }//设置器 setter方法
    // 获取 _name 的值 (取值) //访问器  getter方法
    - (NSString *)getName{
        return _name;//返回实例变量的值
    }
    //为 _age 去赋值
    - (void)setAge:(NSInteger)age{
        _age = age;
    }
    //获取 _age 的值
    - (NSInteger)age{
        return _age;
    }
    //为 _gender 赋值
    - (void)setGender:(NSString *)gender{
        _gender = gender;
    }
    //获取 _gender 的值
    - (NSString *)gender{
        return _gender;
    }
    + (void)methoodForTest{
        //如果有方法,没有实现,那就在 .h 文件里会有警告
        //该方法调用 是需要类名去调用
        NSLog(@"我是一个好人哦");
    }
    + (void)classMethood{
        //1.直接用类名去调用他的类方法。在类中调用 类方法
    //    [Person methoodForTest];
        //2.用 self 去调用类方法
        //self 就是谁调用这个方法(classMethood),那么 self 指代的就是哪个类,此时 self 就是指的 Person 类
        [self methoodForTest];
        NSLog(@"这是一个类方法");
        //在类方法里面调用 对象方法
        Person * per = [[Person alloc]init];
        //拿对象 per 去调用
        [per objectMethood];
        
    }
    //声明对象方法,就是用 - 开头
    - (void)objectMethood{
        NSLog(@"这是一个对象方法");
        //在一个对象方法里 调用 类方法
        [Person classMethood];//直接用类调用
        //2.用 self 去获取当前对象的 类
        [self class];//对象所对应的类 取出来 // - (Class)class;这是 class 的方法 返回的是类  (这里的 self 指代当前类的对象  [self class] 就是获取 self 所在当前的类)
        [[self class]classMethood];// 先看 self 是个什么方法
        //在对象方法里获取 实例变量
        self -> _age;
        //在类方法里能否获取 对象的 实例变量 ????
        //不能 获取, 为什么不能获取        ????
        //因为 ::类 是抽象的概念,作用 除了描述事物的一个特征,为对象创建空间。对象才是一个具象的。对于类来讲,类是抽象的,不占空间的,通过类 去 alloc 所以对象,只有对象才占空间。
        // 实例变量 :是依托对象存在的,所以只有对象存在的前提下,我们的实例变量才有空间。所以说,类方法里不能使用实例变量
        //对象要实实在在存在的
        
    }
    
    //一次性为全部的实例变量赋值
    - (void)setNameOnce:(NSString *)name
                    age:(NSInteger)age
                 gender:(NSString *)gender
                 height:(CGFloat)height
                 weight:(CGFloat)weight{
        _name = name;
        _age = age;
        _gender = gender;
        _heigth = height;
        _weight = weight;
        NSLog(@"%@ %ld %@ %.2f %.2f",name,age,gender,height,weight);
    }
    @end
     person.m 

     参考  

     import 和 include 和 @class  (区别)  

    #include #import @class 讲解
    #include
            区分 #include <x.h>与#include "x.h"的作用
            #include <x.h>:它用于对系统自带的头文件的引用,编译器会在系统文件目录下去查找该文件.
             #include "x.h":用户自定义的文件用双引号引用,编译器首先会在用户目录下查找,然后到安装目录中查找,最后在系统文件中查找。
    
            在使用#include的时候要注意处理重复引用(这也是objc中#include与#import的区别)
            例如:ClassA 与 ClassB同时引用了ClassC,不做重复引用处理的时候在ClassD中同时引用ClassA,ClassB编译会提示对ClassC重复引用的错误.
             我们可以:#ifndef _CLASSC_H
                           #define _CLASSC_H
                           #include "ClassC"
                           #endif
             这样处理在编译时就不会有重复引用的错误出现(在objc中#import解决了这个问题,这是它们的区别)
    
    #import
             #import 大部分功能和#include是一样的,但是他处理了重复引用的问题,我们在引用文件的时候不用再去自己进行重复引用处理.
    
    @class
            主要是用于声明一个类,告诉编译器它后面的名字是一个类的名字,而这个类的定义实现是暂时不用知道的,后面会告诉你.也是因为在@class仅仅只是声明一个类,所以在后面的实现文件里面是需要去#import这个类,这时候才包含了这个被引用的类的所有信息。
    
    综上所述#include,#import与@class的区别可以做一下理解:
    
            #include与#import在引用一个类的时候会包含这个类的所有信息包括变量方法等,但是这样做会对编译效率造成影响.比如有100个类都#import了ClassA,那么在编译的时候这100个类都会去对ClassA处理.又比如A被B引用,B被C引用,C被D引用.....此时如果A被修改,那么后面的B,C,D.....都需要重新进行编译.还有一个用法会引起编译错误的就是在ClassA中#import ClassB 在ClassB中#import ClassA那么在编译的时候也会出现未知错误。
            所以一般来说,在interface中引用一个类,就用@class,它会把这个类作为一个类型来使用,而在实现这个interface的文件中,如果需要引用这个类的实体变量或者方法之类的,还是需要import这个在@class中声明的类。
    (import 和 include 和 @class 区别)

    # import <>  这是导入系统定义的文件

    # import " "   这是导入自定义的文件

    # include  导入文件

    #import   导入文件的是可以避免循环导入(交叉编译)

    @class 的作用是:告诉编译器 class 后面的类存在,但是这个类不会被编译  为了避免循环嵌套导入 如果要使用到 类 ,则需要在 .m 文件里导入相对应的类

  • 相关阅读:
    python基础(6)---set、collections介绍
    Vue Router滚动行为 scrollBehavior
    CSS expression属性
    定时器setTimeout实现函数节流
    axios封装
    vue项目结构
    搭建vue项目环境
    javascript参数传递中处理+号
    微信支付 chooseWXPay:fail
    微信支付get_brand_wcpay_request:fail
  • 原文地址:https://www.cnblogs.com/benpaobadaniu/p/4720048.html
Copyright © 2020-2023  润新知