Objective-C学习笔记

V. 面向对象

V-I 类与对象

  • 类:是某一批对象的抽象,可以把类理解成某种概念;
  • 对象:是一个具体存在的实体。
  • 二者联系:
    1. 类是模版,类的对象是根据模版创建出来的
    2. 类模版中有什么,对象中就有什么

1. 定义类

a. 关键字:@interface 、 @end、@implementation
b. 继承:NSObject
  • 类的三要素:a. 名称 b. 这类事物的特征 c.这类事物具有的共同行为
  • 定义类的语法:
    1. 位置:直接写在源文件中,不用写在main函数中
    2. 类的定义:
    • 类的声明:
   @interface 类名: NSObject{
		这类事物具有的共同特征,将他们定义为变量
	}
	功能就是一个方法,将方法的声明写在这里
	@end
  • 类的实现
@implementation 类名
	将方法的实现写在这里
@end
#import <Foundation/Foundation.h>

@interface Person:NSObject{
    NSString *_name;//*以_开头
    int _age;
    float _height;
}
@end

@implementation Person

@end

int main(int argc, const char * argv[]) {
   	...
    return 0;
}
  • 注意
    1. 类必须要有声明和实现
    2. 类名的第一个字母必须要以大写开头
    3. 用来表示类的特征的变量必须写在@interface的大括号之中
    4. 定义属性时,要以下划线开头

2. 对象的产生和使用

  • 创建对象语法格式:[[类名 alloc] 初始化方法];
    其中alloc是Objective的关键字,负责为该类分配内存空间、创建对象。因为所有对象都继承了NSObject类,所以有默认初始化方法:init。
  • 类定义变量语法格式:类名 * 变量名;
  • 通过对象访问成员变量(访问权限允许):对象->成员变量名

3. 对象与指针

eg:FKPerson *person = [[FKPerson alloc] init];
FKPerson*类型的变量本质是一个指针变量,所以person变量保存了FKPerson对象在内存中的首地址,它被保存在main()函数的的动态存储区,而真正的FKPerson对象放在堆内存中。
Objective-C不允许直接访问堆内存中的对象,只能通过该对象的指针变量来访问该对象。

4. self关键字

`self`关键字总指向该方法的调用者,当self出现在实例方法中时,self代表调用该方法的对象;self出现在类方法中时,self代表调用该方法的类
==作用==:让类中的一个方法访问该类的另一个方法或成员变量

5. id类型

id类型可以代表所有对象的类型,也就是说任何类的对象都可以赋值给id类型的变量
	id p = [Person new];// p = [[Person alloc] init];

V-II 方法详解

1. 方法的所属性

方法是类或对象的行为特征的抽象,从功能上看,方法完全类似于传统结构化程序设计中的函数
在结构化编程语言里,软件是由一个个函数组成的,是一等公民;而在面向对象的编程语言中。类是一等公民。因此,在OC中,方法不能独立存在,方法必须属于类或语言。

  • 定义方法:不能单独定义一个方法,只能在类体中定义。其中若方法使用+标识符,那么这个方法就属于这个;若使用-标识符,则属于这个类的实例
  • 调用:不能独立调用方法,执行方法时必须使用类或对象来作为调用者即[类 方法][对象 方法]

2. 形参个数可变的方法

如果在定义方法时,在最后一个形参名后添加,...,则表明该形参可以接受多个参数;注意:个数可变的形参只能处于形参列表的最后

#import<foundation/foundation.h>
@interface VarArgs : NSObject
- (void)test : (NSString *) name,...;//可接受个数可变的NSString *参数
@end
  • 关键字
  1. va_list:是一个类型,用于定义指向可变参数列表的指针变量
  2. va_start:是一个函数,指定开始处理可变形参的列表,并让指针变量指向可变形参列表的第一个参数
  3. va_end:结束处理可变形参,释放指针变量
  4. va_arg:是一个函数,返回获取指针当前指向的参数的值,并将指针移向下一个参数
#import "VarAegs.h"
@implementation VarArgs
- (void) test: (NSString *)name,...{
    va_list argList;//定义一个va_list类型指针变量
    if(name){//判断第一个参数是否存在
        NSLog(@"%@", name);
        va_start(argList, name);//使argList指向name列表的的第一个参数,开始提取可变参数列表的参数
        NSString *arg = va_arg(argList, id);//用于保存当前获取的参数,如果该参数不为NULL则进入循环体
        while(arg){
            NSLog(@"%@", arg);
            arg = va_arg(argList, id);//提取参数并指向下一个
        }
        va_end(argList);//释放argList指针,结束
    }
}
@end
int main(){
    @autoreleasepool {
        VarArgs *va = [[VarArgs alloc] init];
        [va test: @"hello" @"world",NULL];
    }
}//输出为“helloworld”

V-III 成员变量

根据定义位置的不同,可分为:成员变量、局部变量和全局变量

1. 成员变量及其运行机制

成员变量是指在接口部分或类实现部分定义的变量,OC中的成员变量都是实例变量;实例变量是从该类的实例被创建开始起存在,作用域与对应的实例的生存范围相同
从内存存储的角度,OC的对象与C中结构体类似

  • 语法:实例->实例变量
#import <Foundation/Foundation.h>
@interface Person : NSObject{
    @public//封装的访问控制符
    NSString *_name;//定义实例变量
    int _age;
}
@end
@implementation Person
@end
int main(){
    @autoreleasepool {
        Person *p = [[Person alloc] init];//创建FKPerson对象,并通过指针访问其中的实例变量
        NSLog(@"name:%@ age:%d", p->_name, p->_age);
        p->_age = 10;
        p->_name = @"Objective-C";
        NSLog(@"name:%@ age:%d", p->_name, p->_age);
    }
    return 0;
}//输出结果:NULL 0
		   Objective-C 10

上面的实例中,成员变量无需初始化,系统会默认初始化,基本类型的实例变量默认初始化为0;指针类型的成员变量默认初始化为NULL

2. 模拟类变量

通过内部全局变量来模拟类变量

#import <Foundation/Foundation.h>
@interface User : NSObject
    + (NSString*) nation;
    + (void) setNation:(NSString *) newNation;
@end
 
//实现
static NSString * nation = nil;//定义一个static修饰的全局变量
@implementation User
    + (NSString*) nation{
        return nation;//返回nation全局变量
    }
 
    + (void) setNation:(NSString *)newNation{
        //对nation全局变量赋值
        if(![nation isEqualToString:newNation])
        {
            nation = newNation;
        }
    }
@end
 
int main() {
    @autoreleasepool {
        //为User类变量赋值
        [User setNation:@"People"];
        NSLog(@"User 的 nation 类变量为:%@",[User nation]);//访问User的类变量
    }
    return 0;
}

  • 注意:OC中的static关键字不能用于修饰成员变量,只能修饰局部变量、全局变量和函数。其中 static修饰局部变量表示将该局部变量存储到静态存储区;static修饰全局变量限制该全局变量只能在当前源文件中访问;static修饰函数限制该函数只能在当前源文件中调用

3. 单例模式

V-IV 隐藏和封装

1. 理解封装

封装是面向对象的三大特性之一(继承和多态),是指将对象的状态和信息隐藏在对象内部,不允许外部程序直接访问对象内部的信息,而是通过该类所提供的方法来实现对内部信息的操作和访问
目的:

  1. 隐藏类的实现细节
  2. 让使用者只能通过实现预定的方法访问数据,可在方法中加入控制逻辑(比如说年龄一般不超过140岁,月份不超过12月),限制对成员变量不合理的访问
  3. 可进行数据检查,从而有利于保证对象信息的完整性
  4. 便于修改,提高代码可维护性

考虑的方面:

  1. 把对象的成员变量和实现细节隐藏起来,不允许外部直接访问
  2. 把方法暴露出来,让方法来控制对这些成员变量进行安全的访问和操作

2. 使用访问控制符

优先级
在这里插入图片描述

  • @private(当前类访问权限):成员变量只能在当前类的内部访问;其用于彻底隐藏成员变量
  • @package(相同映像访问权限):成员变量可以在当前类以及当前类的同一个映像的任意地方访问;其用于部分隐藏成员变量
  • @protected(子类访问权限):成员变量可以在当前类、当前子类的任意地方访问;其用于部分暴露成员变量
  • @public(公共访问权限):成员变量可以在任意地方访问
    在这里插入图片描述

Tips

1.#import

  1. 是一个预处理命令
  2. 作用:相当于C语言中的#include,是#include指令的增强版
  3. 与#include的区别:同一个文件无论#import多少次,只会包含一次
  4. 原理:#import指令在包含文件时,底层会先判断这个文件是否被包含,如果包含则直接跳过。

2.NSLog函数

  1. 作用:相当于C语言中的printf,是printf函数的增强版
  2. 语法:NSLog(@"一个字符串直接量")
  3. 与printf区别:
    a. 在输出完信息后,会自动换行
    b. 不仅可以输出字符串,也可以输出整数、C风格字符串和Objective-C对象
    c. 输出调试相关信息(时间、程序名称、进程编号、线程编号、输出信息)

3.NSString函数

  1. NSString类型的指针变量专门用来存储OC字符串的地址
    a. OC字符串常量必须要用到一个前缀@符号:
    "jack"是C语言字符串
    @“jack”是OC字符串常量
    b. NSString *str = @"jack"指针类型
    c. 要使用NSLog函数输出OC字符串的值则用%@占位符
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值