OC语言自学基础知识总结

  • 一、成员变量的作用域
  • 二、点语法
  • 三、构造方法
  • 四、分类
  • 五、类的本质
  • 六、自动生成getter和setter方法
  • 七、description方法
  • 八、id类型
  • 九、SEL

一、成员变量的作用域

  • @public
    • 在任何地方都能直接访问对象的成员变量
  • @private
    • 只能在当前类的对象方法中访问
  • @protected(可以不写,默认)
    • 能在当前类和子类的对象方法中直接访问
  • @package
    • 只要处在同一个框架中,就能直接访问对象的成员变量
  • @interface和@implementation中不能声明同名的成员变量
  • 在@implementation中声明变量,默认是@private的

二、点语法

  • 点语法的本质还是方法调用,不是调用成员变量
  • 编译器遇到点语法时,会把点语法转成方法

?


1

2

3

p.age = 10;         //[p setAge:10];

int age = p.age;    //[p age];

三、构造方法

  • 用来初始化对象的方法,对象方法,以减号开头
  • 为了让对象创建出来,成员变量就会有一些固定的值
  • 重写构造方法的注意点:
    • 先调用父类的构造方法([super init])
    • 再进行子类内部成员变量的初始化
  • + alloc 方法
    • 分配存储空间
  • - init 方法
    • 初始化
  • 实际上是这么创建对象的

?


1

Person *p5 = [[Person alloc] init];    //先分配存储空间,再进行初始化

  • 重写NSObject类的init方法(无参数)

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

- (id)init

{

    //一定要调用回super得init方法:初始化父类中声明的一些成员变量和其他属性

    if (self = [super init]) {

        //初始化成功

        _age = 10;

    }

    return self;  

}

  • 带参数的构造方法

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

- (id)initWithName:(NSString *)name andAge:(int)age

{

    if (self = [super init]) {

        _age = age;

        _name = name;

    }

    return self;

}

四、分类

  • 分类,在不改变原来模型的情况下,可以给某个类扩充一些方法
  • 分类只能增加方法, 不能增加成员变量
  • 分类方法实现中可以访问原来类中声明的成员变量
  • 分类的优先级最高,方法优先去分类中去找,再去原来类中去找,最后再去父类中找
  • 分类可以重写原来类中的方法,但是会覆盖掉,会导致原来的方法失效,没法再使用
  • 方法调用的优先级:分类(最后参与编译的分类优先) --> 原来类 --> 父类
  • 分类的应用一般是扩展系统的类的方法,比如扩展NSString类的方法

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

+ (int)numberCountOfString:(NSString *)str

{

    int count = 0;

    for (unsigned long i = 0; i < [str length]; i++) {

        unichar ch = [str characterAtIndex:i];

        if (ch >= ‘0‘ && ch <=‘9‘) {

            count++;

        }

    }

    

    return count;

    //return [str numberCount];

}

//计算某个字符串中阿拉伯数字的个数(对象方法)

- (int)numberCount

{

    int count = 0;

    for (unsigned i = 0 ; i < [self length]; i++) {

        unichar ch = [self characterAtIndex:i];

        if (ch >= ‘0‘ && ch <=‘9‘) {

            count++;

        }

    }

    

    return count;

    //return [NSString numberCountOfString:self];

}

五、类的本质

  • 可以使用类创建对象,但是类本身也是一个对象,是个Class类型的对象,简称“类对象
  • 先利用Class创建一个Person类对象,再利用Person类对象,创建Person类型的对象
  • 重写load()方法和initialize()方法

?


1

2

3

4

5

6

7

8

9

10

11

+ (void)load

{

    NSLog(@"Student的load方法被调用");

}

//在第一次被使用的时候就会被调用一次,监听类第一次被使用的时候

+ (void)initialize

{

    NSLog(@"Student-initialize方法被调用");

}

  • load()方法:
    • 当程序启动时,就会加载项目中所有的类和分类,而且加载后会调用每个类和分类的load方法。只会调用一次
    • 当第一次使用某个类时,就会调用当前类的+initialize方法
    • 先加载父类,再加载子类(先调用父类的load方法,再调用子类的load方法)
    • 先初始化父类,再初始化子类(先调用父类的initialize方法,再调用子类的initialize方法

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

//利用Person这个类创建了3个Person类型的对象

Person *p = [[Person alloc] init];

Person *p2 = [[Person alloc] init];

Person *p3 = [[Person alloc] init];

//先利用Class创建一个Person类对象   

//再利用Person类对象,创建Person类型的对象

//获取内存中的类对象

Class c = [p class];

Class c2 = [p class];

//获取内存中的类对象

Class c3 = [Person class];

NSLog(@"c=%p,c2=%p,c3=%p",c,c2,c3);  //c的地址等于c2,也等于c3

//程序先加载父类,再加载子类,而且类只被加载一次

//只要加载了类,就会调用load类方法

//initialize类方法是在类第一次被初始化时,被调用,如果在使用子类的时候,父类也会被调用该方法

//分类也会被加载,如果原始类和分类都重写了initialize方法,那么分类的initialize方法优先被调用,原始类不调用

GoodStudent *stu = [[GoodStudent alloc] init];

六、自动生成getter和setter方法

  • @property自动生成某个成员变量的声明
  • @synthesize自动生成getter和setter的实现,并且会访问指定的成员变量

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

//自动生成某个成员变量的声明

//编译器特性:编译器当遇到@property时,自动转换成setter和getter声明方法

// - (void)setAge:(int)age;

// - (int)age;

@property int age; //生成_age成员变量

@property double height; //生成_height成员变量

@property double weight; //生成_weight成员变量

@property NSString *name;    //生成_name成员变量

//@synthesize自动生成getter和setter的实现,并且会访问指定的成员变量

@synthesize age = _age;

@synthesize height = _height;

//用逗号分隔

@synthesize weight = _weight,name = _name;

  • @synthesize可以不写,只写@property就可以完成成员变量getter和setter方法的声明和实现

七、description方法

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

#import <Foundation/Foundation.h>

#import "Person.h"

int main()

{

    //输出行号

    NSLog(@"%d",__LINE__);

    //NSLog输出C语言字符串的时候,不能有中文

    NSLog(@"%s",__FILE__);

    //输出源文件路径名称

    printf("%s\n",__FILE__);

    //输出当前函数名

    NSLog(@"%s",__func__);

    return 0;

}

void test()

{

    Person *p = [[Person alloc] init];

    p.age = 20;

    p.name = @"Jack";

    

    //1.首先会调用对象的-description方法,返回字符串

    //2.拿到-description方法的返回值,并显示到屏幕上

    //description方法默认返回“类名+内存地址” <Person 0x0232010>

    //所以需要重写description方法

    //相当于java的Object的toString()方法

    NSLog(@"%@",p.description);

    Person *p2 = [[Person alloc] init];

    p2.age = 22;

    p2.name = @"Ted";

    NSLog(@"%@",p2.description);

}

void test2()

{

    Class c = [Person class];

    //1.首先会调用类的+description方法

    //2.拿到+description方法的返回值(NSString *)显示到屏幕上

    NSLog(@"%@",c);

}

//重写description方法

- (NSString *)description

{

    //死循环

    //NSLog(@"%@",self);

   

    return [NSString stringWithFormat:@"age=%d,name=%@",_age,_name];

}

+ (NSString *)description

{

    return @"sss";

}

八、id类型

  • id是一种类型
  • id是万能指针,能操作任何OC对象,id内部已经包含*,所以不用再加*
  • 示例:

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

int main()

{

    //id是一种类型

    //id是万能指针,能操作任何OC对象,id内部已经包含*,所以不用再加*

    //id d;

      

    //Person *p = [Person new];

        

    //id == NSObject*

    //NSObject *o = [Person new];

   

    //只适用OC对象

    id person = [Person new];

    [person setAge:10];

    [person setObj:@"luoguankun"];

    NSLog(@"age=%d",[person age]);

    test(person);

    

    return 0;

}

九、SEL

  • SEL其实是对方法的一种包装,将方法包装成一个SEL类型的数据,去找对应的方法地址,找到方法地址就可以调用方法
  • 其实消息就是SEL

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

int main()

{

    //[Person test];

    Person *p = [[Person alloc] init];  

    //1.把test2包装成SEL类型的数据

    //2.根据SEL数据找到对应的方法地址

    //3.根据方法地址调用对应的方法

    //[p test2];

    //通过SEL简介调用test方法

    [p performSelector:@selector(test2)];

    //上面的调用相当于下面这两步

    //SEL s = @selector(test2);

    //[p performSelector:s];

    

    //通过SEL带参数的形式调用test3方法,不要忘了带上冒号

    [p performSelector:@selector(test3:andluo:) withObject:@"luo" withObject:@"feng"];

    return 0;

}

//字符串转换成SEL

NSString *name = @"test2";

SEL s = NSSelectorFromString(name);

//SEL转换成字符串

- (void)test2

{

    //死循环

    //[self performSelector:_cmd];

    

    //_cmd是SEL类型,代表当前方法

    //通过NSString的fromSelector方法把SEL转换为字符串

    NSString *str = NSStringFromSelector(_cmd);

    //打印_cmd

    NSLog(@"%@",str);   //打印test2

}

 

时间: 2024-10-27 08:31:36

OC语言自学基础知识总结的相关文章

Java语言的基础知识

第三章 1.在java源文件编辑器中,选择某个成员变量,然后按住shift+alt+j,Eclipse会自动添加JavaDoc文档注释结构,如果选择的是方法,还会自动添加参数名称. 2.Java语言规定标示符是由任意的字母.下划线.美元符号和数字组成,并且第一个字符不能使数字,标示符不能使java中的保留关键字. 3.在Java语言中允许使用汉字或其他语言文字作为变量名,如int 年龄 =21;在程序运行时不会报错,但建议尽量不要使用这些语言作为变量. 4.java用关键字final来声明常量,

R语言常用基础知识

seq(from = 1, to = 1, by = ((to - from)/(length.out - 1)),    length.out = NULL, along.with = NULL, ...) 举例----------Examples----------seq(0, 1, length.out=11) seq(stats::rnorm(20)) #  seq(1, 9, by = 2)     #  seq(1, 9, by = pi)    #  seq(1, 6, by =

Java语言的基础知识4

第五章(数组) 1.在Java中可以将数组看做是一个对象虽然基本数据类型不是对象但有基本数据类型组成的数组是对象. 2.对于二维数组求第二维就用array[0].length, array.length就是默认的是第一维的长度. 3.foreach并不是一个新的语法它是for的循环的格式化主要执行遍历功能的循环,example: int arry ={1,2,3,4,5}; for(int i :array){ system.out.println(): } 4.数组元素定义完以后可通过Arra

Java学习-033-JavaWeb_002 -- 网页标记语言JSP基础知识

JSP 是 Sun 公司提倡的一门网页技术标准.在 HTML 文件中,加入 Java 代码就构成了 JSP 网页,当 Web 服务器访问 JSP 请求的时候,首先执行其中的 Java 程序源码,然后以 HTML 形式返回, Java 程序运行在服务端,最终显示在客户端.JSP 源于 Java,因而 JSP 的运行环境依赖JDK,当然也需要服务器软件(例如 Tomcat 等). 一.运行环境搭建 1.安装 JDK,请参阅之前的博文:Java学习-001-JDK安装配置 2.Tomcat部署及环境变

Oracle的DML语言必备基础知识

原文:Oracle的DML语言必备基础知识 前提是咱们都已经对常用的数据操纵语言非常熟悉了,对标准SQL: SELECT子句                --指定查询结果集的列 DROM子句                 --指定查询来自哪个表或者试图 [WHERE 子句]              --指定查询的条件 [GROUP BY 子句]           --指定查询结果集的分组的条件 [HAVING 子句]             --指定分组或者集合的查询条件 [ORDERB

Java语言的基础知识12

第十四章(使用集合类保存对象) 1.java中得集合对象就像是一个容器,它用来存放Java类的对象.Java中的集合类有些方便存入和取出,有些则方便查找.集合类和数组的区别是,数组的长度是固定的,集合的长度是可变的,数组用来存放基本类型,集合用来存放对象的引用.常用的集合类有List集合,Set集合,和Map集合. 2.List集合包括List接口以及List接口的所有实现类.List集合中的元素许重复,个元素的顺序就是对象插入的顺序.类似java中的数组.List类继承了Collection接

Java语言的基础知识10

第十二章(GUI事件) 1.GUI事件的处理机制是建立交互式应用程序的关键技术,其中事件是用在程序界面上的各种操作. 2.写程序的时候对于swing的一些空间譬如jprogressbar ,jtextfield等空间在全局中声明以后,用的时候一定要new 一下,自己经常忘记(由于对java理解不深) private  JTextField textField2; textField2 = new JTextField(); 3.事件在java语言中也是一种对象 4.监听器接受到事件之后,将委托指

Java语言的基础知识9

第十一章(线程) 1.通过String name=Thread.currentThread().getName();来获取当前线程的名称. 2.多次启动一个线程或者启动一个已经运行的线程是非法的,会抛出IllegalThreadStateException异常对象. Thread.sleep((int)Math.random()*10000); 3.java提供了Runnable接口使继承了其他类之后同样可以实现该接口达到创建线程的目的Runabble接口同样定义了Run方法. 实现Runnab

Java语言的基础知识3

第四章 1.sum +=x++;的语句等价于sum=sum+x;和x=x+1;两条语句 2.do....while循环语句与while循环语句类似.他们之间的差别是while语句为先判断条件是否成立再执行循环体,而do...while循环语句是先执行一次循环体,在判断条件是否成立.也就是说do....while循环语句至少执行一次循环体. 3.在一个循环语句中又包含另外一个完整的循环语句,称为嵌套循环,笔者不建议使用超过3层的嵌套循环,因为这样会使程序更加难以阅读. 4.乘法口诀中用到的制表符"