(转载)OC学习篇之---类的初始化方法和点语法的使用

昨天介绍了OC中类的定义和使用,今天我们来继续学习类的初始化方法和点语法的使用。

一、首先来看一下类的初始化方法

在Java中我们知道一个每个类都有构造方法,这里的初始化方法就是和构造方法一个概念的,但是这里有一个区别是:Java中有默认构造方法,当我们去自定义构造方法的时候,这个默认构造方法就会被替换了,但是OC中是不会的,这点需要注意。

下面来看一下如何自定义初始化方法:

Person.h

 1 //
 2 //  Person.h
 3 //  03_InitDemo
 4 //
 5 //  Created by jiangwei on 14-10-10.
 6 //  Copyright (c) 2014年 jiangwei. All rights reserved.
 7 //
 8
 9 #import <Foundation/Foundation.h>
10
11 @interface Person : NSObject{
12     NSString *_name;
13     NSInteger _age;
14 }
15
16 //自定义初始化方法,必须以init开头
17 - (id)initWithName:(NSString *)name withAge:(NSInteger)age;
18
19 //打印信息
20 - (void)showInfo;
21
22 @end  

这里我们定义了一个初始化方法,对名称和年龄进行初始化赋值操作

注:OC中自定义初始化方法的名称必须是以init开头

在来看一下实现:

Person.m

 1 //
 2 //  Person.m
 3 //  03_InitDemo
 4 //
 5 //  Created by jiangwei on 14-10-10.
 6 //  Copyright (c) 2014年 jiangwei. All rights reserved.
 7 //
 8
 9 #import "Person.h"
10
11 @implementation Person
12
13 - (id)initWithName:(NSString *)name withAge:(NSInteger)age{
14     //固定写法,可以背下来哦~~
15
16     //调用父类的初始化方法
17     self = [super init];
18
19     if(self != nil){
20         _name = name;
21         _age = age;
22     }
23
24     return self;
25 }
26
27 - (void)test{
28     NSLog(@"test");
29 }
30
31 - (void)showInfo{
32     [self test];//调用自己的方法
33     NSLog(@"name is %@ and age is %d",_name,_age);
34 }
35
36 @end  

这里我们看到了,初始化方法返回的类型是id类型,关于OC中的id类型,可以认为和C语言中的void*是相等的,这种类型在OC中经常被用到,还有就是self关键字的使用,这里的self关键字就相当于Java中的this关键字,指代当前类对象,还有super关键字,这个和Java中的super也是一样的,指代父类对象。还有一个是nil,他就相当于Java中的null,空对象的概念,用于判断的。

同时这里还要记住一点:

以后OC中自定义初始化的方法的模板:

1 //固定写法,可以背下来哦~~
2 //调用父类的初始化方法
3 self = [super init];
4 if(self != nil){
5     _name = name;
6     _age = age;
7 }
8 return self;  

这个没什么好说的,就是一个模板,所以初学者就背下来吧,不过用多了,自然就记住了。

下面来看一下如何使用初始化方法:

main.m

 1 //
 2 //  main.m
 3 //  03_InitDemo
 4 //
 5 //  Created by jiangwei on 14-10-10.
 6 //  Copyright (c) 2014年 jiangwei. All rights reserved.
 7 //
 8
 9 #import <Foundation/Foundation.h>
10
11 #import "Person.h"
12
13 int main(int argc, const charchar * argv[]) {
14     @autoreleasepool {
15         //初始化方法只能调用一次
16         Person *person = [[Person alloc] initWithName:@"jiangwei" withAge:22];
17         [person showInfo];
18
19         person = [[Person alloc] init];
20         [person showInfo];
21
22         //id类型,类似于void*
23         //但是id类型一般不这么使用,一般会作为方法的返回值和传入的参数类型
24         id person1 = [[Person alloc] initWithName:@"huangdaoyang" withAge:23];
25         [person1 showInfo];
26     }
27     return 0;
28 } 

我们使用了我们自定义的方法实例化了一个Person对象出来,同时调用他的showInfo方法,打印结果,这里我们也会发现Person的init方法任然可以使用,这个和Java中是有区别的,其实,在上篇文章中说到过,这个init方法是NSObject父类的,可以猜想到这个方法的逻辑功能就是初始化,所以我们在自定义初始化方法的时候,都是会用到这个方法的。当然我们可以定义多个初始化方法,后面我们在介绍Foundation框架的时候,会发现系统给我提供的类有很多自定义的初始化方法。

运行结果:

二、看一下OC中的点语法

OC中的点语法其实没什么高端的,但是他和Java中的那种使用对象变量直接访问public类型的变量的点是不一样的,所以这里就单独说明一下:

点语法只能适用于set/get方法,如果没有对应的set/get方法的话,是不能使用.语法的

OC中的get方法和Java中不太一样,OC中只要一个方法有返回值都可以认为是get方法,Java中是形如getXXX这样的才叫做get方法。

下面来看一个例子吧:

Person.h

 1 //
 2 //  Person.h
 3 //  04_UseDit
 4 //
 5 //  Created by jiangwei on 14-10-11.
 6 //  Copyright (c) 2014年 jiangwei. All rights reserved.
 7 //
 8
 9 #import <Foundation/Foundation.h>
10
11 @interface Person : NSObject{
12     //点语法只能适用于set/get方法,如果没有对应的set/get方法的话,是不能使用.语法的
13     //这里的get方法和其他语言不一样,只要有返回值就是get方法
14     NSString *_name;
15     NSInteger _age;
16 }
17
18 - (void)setName:(NSString *)name;
19 - (void)setAge:(NSInteger)age;
20
21 - (NSString *)name;
22 - (NSInteger) age;
23
24 //这里要注意,showInfo也是一个get方法
25 - (NSString *)showInfo;
26
27 //只定义,不实现,所以在调用[person test]的时候,编译时候不会报错
28 //但是运行的时候就会报错了,因为编译的时候只会判断方法有没有定义,而运行的时候是需要判断这个方法有没有实现
29 - (void)test;
30
31 @end  

在{}中定义了两个属性,注意都是以下划线开头的。然后在给这两个属性定义get/set方法,这样我们就可以使用点语法来访问这两个属性了。

同时这里要注意的是其实showInfo方法也是一个get方法,因为他又一个返回值类型。

所以在OC中使用点语法有两个条件:

1、必须是属性

2、有对应的get/set方法

下面来看一下实现吧:

Person.m

 1 //
 2 //  Person.m
 3 //  04_UseDit
 4 //
 5 //  Created by jiangwei on 14-10-11.
 6 //  Copyright (c) 2014年 jiangwei. All rights reserved.
 7 //
 8
 9 #import "Person.h"
10
11 /**
12  #import和#include的区别
13     1.当我们在代码中使用两次#include的时候会报错:因为#include相当于拷贝头文件中的声明内容,所以会报重复定义的错误
14       但是使用两次#import的话,不会报错,所以他可以解决重复导入的问题,他会做一次判断,如果已经导入一次就不导入了
15  */
16
17 @implementation Person
18
19 - (void)setName:(NSString *)name{
20     _name = name;
21     NSLog(@"setName is Execute");
22 }
23 - (void)setAge:(NSInteger)age{
24     //这里要注意,如果我们定义的全局变量是age而不是_age的话
25     //这里不能用age = age进行赋值
26     //但是也不能使用self.age = age,因为self.age等价于[self setAge:age]这样就会出现死循环了
27     //所以我们在定义全局变量的时候一般都会加上一个下划线以便区分
28     _age = age;
29     NSLog(@"setAge is Execute");
30 }
31 - (NSString *)name{
32     NSLog(@"getName is Execute");
33     return _name;
34 }
35 - (NSInteger) age{
36     NSLog(@"getAge is Execute");
37     return _age;
38 }
39 - (NSString *)showInfo{
40     NSLog(@"showInfo is Execute");
41     return _name;
42 }
43
44 @end  

我们看到了这里对get/set方法的实现,看到上面的注释:

我们这里不能使用self.age = age,因为self.age等价于[self setAge:age],这样就会出现死循环了

这个和Java就有很大的区别了,Java中我们是可以使用this.age = age的,而且经常这样做,但是OC中不行,原因很简单,因为OC中的点语法相当于调用set/get方法,那么在set/get方法中调用set/get方法,那就会出现了死循环了。所以这点一定要注意。

还有一个需要注意的是,刚刚在Person.h中定义了一个test方法,但是在Person.m中并没有实现,在OC中编译是不会报错的,但是运行的时候就会报错了。

看一下如何使用点语法:

main.m

 1 //
 2 //  main.m
 3 //  04_UseDit
 4 //
 5 //  Created by jiangwei on 14-10-11.
 6 //  Copyright (c) 2014年 jiangwei. All rights reserved.
 7 //
 8
 9 #import <Foundation/Foundation.h>
10
11 #import "Person.h"
12
13 int main(int argc, const charchar * argv[]) {
14     @autoreleasepool {
15         Person *person = [[Person alloc] init];
16         //此处的点语法调用的是set方法,等价于[person setName:@"jiangwei"];
17         person.name = @"jiangwei";
18         person.age = 22;
19         //此处的点语法调用的get方法,等价于NSString *name = [person name];
20         NSString *name = person.name;
21         NSLog(@"name is %@",name);
22
23         name = person.showInfo;
24         NSLog(@"name is %@",name);
25
26         //调用test方法
27         [person test];
28     }
29     return 0;
30 }  

我们这里就可以使用点语法进行赋值和取值操作了,其实等价于调用他们的get/set方法。

运行结果:


这里需要注意的是报了一个错误,这个错误也是我们后面开发过程中经常犯的一个错误,就是这个方法没有实现,我们在Person.h中定义了test方法,但是没有在Person.m中进行实现,在main.m中进行调用就报了这个错误,但是编译的时候是没有报错的。

总结

今天就简单的介绍了OC中的初始化方法的定义和点语法的使用,其中初始化方法类似于Java中的构造方法,点语法就是get/set的缩减版

时间: 2024-12-05 00:32:43

(转载)OC学习篇之---类的初始化方法和点语法的使用的相关文章

OC学习篇之---类的初始化方法和点语法的使用

一.首先来看一下类的初始化方法 在Java中我们知道一个每个类都有构造方法,这里的初始化方法就是和构造方法一个概念的,但是这里有一个区别是:Java中有默认构造方法,当我们去自定义构造方法的时候,这个默认构造方法就会被替换了,但是OC中是不会的,这点需要注意. 下面来看一下如何自定义初始化方法: Person.h [objc] view plain copy // //  Person.h //  03_InitDemo // //  Created by jiangwei on 14-10-1

(转载)OC学习篇之---类的三大特性:封装,继承,多态

之前的一片文章介绍了OC中类的初始化方法和点语法的使用,今天来继续学习OC中的类的三大特性,我们在学习Java的时候都知道,类有三大特性:继承,封装,多态,这个也是介绍类的时候,必须提到的话题,那么今天就来看一下OC中类的三大特性: 一.封装 学习过Java中类的同学可能都知道了,封装就是对类中的一些字段,方法进行保护,不被外界所访问到,有一种权限的控制功能,Java中有四种访问权限修饰符:public,default,protected,private,访问权限一次递减的,这样我们在定义类的时

OC学习篇之---类的三大特性(封装,继承,多态)

之前的一片文章介绍了OC中类的初始化方法和点语法的使用:http://blog.csdn.net/jiangwei0910410003/article/details/41683873,今天来继续学习OC中的类的三大特性,我们在学习Java的时候都知道,类有三大特性:继承,封装,多态,这个也是介绍类的时候,必须提到的话题,那么今天就来看一下OC中类的三大特性: 一.封装 学习过Java中类的同学可能都知道了,封装就是对类中的一些字段,方法进行保护,不被外界所访问到,有一种权限的控制功能,Java

(转载)OC学习篇之---类的定义

之前已经介绍了OC中的一个程序HelloWorld,今天我们继续学习OC中类的相关知识. OC和C的最大区别就是具有了面向对象的功能,那么说到面向对象,就不得不说类这个概念了,如果学过Java的话,那么对类和对象的概念就不陌生了,因为Java是非常纯正的面向对象设计语言.关于类和对象的概念,这里就不仔细介绍了,网上有各种解释.我们之间来开一下OC中如何定义一个类,如何实例化出一个对象等. 首先我们新建一个工程,系统会自动创建main.m文件的,这时候,我们右键项目,选择New File.. 然后

OC学习篇之---类的定义

之前已经介绍了OC中的一个程序HelloWorld:http://blog.csdn.net/jiangwei0910410003/article/details/41578003,今天我们继续学习OC中类的相关知识. OC和C的最大区别就是具有了面向对象的功能,那么说到面向对象,就不得不说类这个概念了,如果学过Java的话,那么对类和对象的概念就不陌生了,因为Java是非常纯正的面向对象设计语言.关于类和对象的概念,这里就不仔细介绍了,网上有各种解释.我们之间来开一下OC中如何定义一个类,如何

(转载)OC学习篇之---类的延展

前一篇文章我们介绍了类的类目概念和使用,那么这篇文章我们继续来介绍一下OC中的一个特性:延展. 其实说白了,延展就是弥补C语言中的前向申明,我们知道,在C语言中,如果你想调用一个函数的话,那么在此之前必须要声明一个这个函数,就是有前置性. OC中为了弥补C语言中的这个问题,就有了延展的概念,下面来看一下代码: Person.h 1 // 2 // Person.h 3 // 10_CategoryExtend 4 // 5 // Created by jiangwei on 14-10-11.

(转载)OC学习篇之---类目的概念和使用

上一篇文章介绍了OC中的@class关键字的使用,这一篇我们介绍一下,OC中的一个特有的亮点:类目 首先我们来看一下场景,如果我们现在想对一个类进行功能的扩充,我们该怎么做? 对于面向对象编程的话,首先会想到继承,但是继承有两个问题: 第一个问题:继承的前提是这个类可以被继承,因为在Java中有些类是不允许继承的,定义成final类,同样的OC中也是有不可以继承的类. 第二个问题:这个类可以被继承,但是继承我们知道是侵入性的,就是我可能只是想实现一个功能,但是继承之后,子类就会把父类的所有功能(

OC学习篇之---类的延展

前一篇文章我们介绍了类的类目概念和使用:http://blog.csdn.net/jiangwei0910410003/article/details/41775329,那么这篇文章我们继续来介绍一下OC中的一个特性:延展 其实说白了,延展就是弥补C语言中的前向申明,我们知道,在C语言中,如果你想调用一个函数的话,那么在此之前必须要声明一个这个函数,就是有前置性. OC中为了弥补C语言中的这个问题,就有了延展的概念,下面来看一下代码: Person.h // // Person.h // 10_

OC学习篇之---类目的概念和使用

上一篇文章介绍了OC中的@class关键字的使用http://blog.csdn.net/jiangwei0910410003/article/details/41774747,这一篇我们介绍一下,OC中的一个特有的亮点:类目 首先我们来看一下场景,如果我们现在想对一个类进行功能的扩充,我们该怎么做? 对于面向对象编程的话,首先会想到继承,但是继承有两个问题: 第一个问题:继承的前提是这个类可以被继承,因为在Java中有些类是不允许继承的,定义成final类,同样的OC中也是有不可以继承的类 第