「OC」点语法和成员变量的作用域

时间:2023-03-08 16:30:54
「OC」点语法和成员变量的作用域

一、点语法

  (一)认识点语法

    声明一个Person类:

「OC」点语法和成员变量的作用域
 1 #import <Foundation/Foundation.h>
2
3 @interface Person : NSObject
4 {
5 int _age;
6 NSString *_name;
7 }
8
9 - (void)setAge:(int)age;
10 - (int)age;
11
12 - (void)setName:(NSString *)name;
13 - (NSString *)name;
14
15 @end
「OC」点语法和成员变量的作用域

    Person类的实现:

「OC」点语法和成员变量的作用域
 1 #import "Person.h"
2
3 @implementation Person
4 - (void)setAge:(int)age
5 {
6 _age = age;
7 NSLog(@"setAge");
8
9 //会引发死循环
10 //self.age = age; // [self setAge:age];
11 }
12 - (int)age
13 {
14 NSLog(@"age");
15 return self->_age;
16
17 //会引发死循环
18 //return self.age; // [self age];
19 }
20 - (void)setName:(NSString *)name
21 {
22 _name = name;
23 }
24 - (NSString *)name
25 {
26 return _name;
27 }
28 @end
「OC」点语法和成员变量的作用域

    点语法的使用:

「OC」点语法和成员变量的作用域
 1 #import <Foundation/Foundation.h>
2 #import "Person.h"
3
4 int main(int argc, const char * argv[])
5 {
6 Person *p = [Person new];
7
8 // 点语法的本质还是方法调用
9 p.age = 10; // [p setAge:10];
10 int a = p.age; // [p age];
11
12 NSLog(@"%d",a);
13
14 p.name = @"Jack";
15 NSString *s = p.name;
16
17 NSLog(@"%@",s);
18
19 return 0;
20 }
「OC」点语法和成员变量的作用域

  (二)点语法的作用

    OC设计点语法的目的,是为了让其他语言的开发者可以很快的上手OC语言开发,使用点语法,让它和其他面向对象的语言如java很像。

  (三)点语法的本质

    点语法的本质是方法的调用,而不是访问成员变量,

    当使用点语法时,编译器会自动展开成相应的方法。

    实际上是转换成相应的setter和getter,如果没有setter和getter,则不能使用点语法。

    如:

      stu.age=10;展开为:[stu setAge:10];

      int  a=stu.age;展开为:[stu age];

    编译器如何知道是set方法还是get方法?主要是看赋值(可以使用断点调试来查看)。

    在OC中访问成员变量只有一种方式即使用-> 如stu->age,这种情况要求在@public的前提下。

  (四)点语法的使用注意

    下面的使用方式是一个死循环:

      (1)在set方法中,self.age=age;相当于是[self setAge:age];

      (2)在get方法中,return self.age;相当于是[self age];

二、变量作用域

  (一)变量的作用域主要分为四种:

    (1)@public (公开的)在有对象的前提下,任何地方都可以直接访问。

    (2)@protected (受保护的)只能在当前类和子类的对象方法中访问

    (3)@private (私有的)只能在当前类的对象方法中才能直接访问

    (4)@package (框架级别的)作用域介于私有和公开之间,只要处于同一个框架中就可以直接通过变量名访问

  (二)使用注意和补充

    (1)在类的实现即.m文件中也可以声明成员变量,但是因为在其他文件中通常都只是包含头文件而不会包含实现文件,所以在这里声明的成员变量是@private的。在.m中定义的成员变量不能喝它的头文件.h中的成员变量同名,在这期间使用@public等关键字也是徒劳的。

    (2)在@interface  @end之间声明的成员变量如果不做特别的说明,那么其默认是protected的。

    (3)一个类继承了另一个类,那么就拥有了父类的所有成员变量和方法,注意所有的成员变量它都拥有,只是有的它不能直接访问。

  (三)代码演示:  

 Person.h
 Person.m
 Student.h
 Student.m

  main.m

「OC」点语法和成员变量的作用域
 1 #import <Foundation/Foundation.h>
2 #import "Person.h"
3 #import "Student.h"
4
5 @implementation Car : NSObject
6 {
7 @public
8 int _speed;
9
10 @protected
11 int _wheels;
12 }
13
14 - (void)setSpeed:(int)speed
15 {
16 _speed = speed;
17 }
18 - (int)speed
19 {
20 return _speed;
21 }
22
23 @end
24
25 int main(int argc, const char * argv[])
26 {
27
28 @autoreleasepool {
29 Student *stu = [Student new];
30
31
32 [stu setHeight:100];
33
34
35 NSLog(@"%d", [stu height]);
36
37 /*
38 Car *c = [Car new];
39 c->_speed = 250;
40 */
41 //c.speed = 10;
42
43 // NSLog(@"%d", c.speed);
44
45 //[c setSpeed:<#(int)#>];
46
47 /*
48 Person *p = [Person new];
49 p->_bbb = 10;
50 p->_age = 100;
51 */
52 //p->_height = 20;
53
54
55 //p->_weight = 10;
56 }
57 return 0;
58 }
「OC」点语法和成员变量的作用域