目录

Objective-C_02.语言基础知识

一、面向对象

OC语言是面向对象的,C语言是面向过程的,面向对象和面向过程只是解决问题的两种思考方式,面向过程关注的是解决问题涉及的步骤,面向对象关注的是设计能够实现解决问题所需功能的类。

术语:OO面向对象、OOP面向对象编程

二、类

(一)关于类

类的设计只关注三个东西:类名、属性和方法

注意:一般名词都是类,拥有相同属性和行为的对象都可以抽象为一个类,类名是标识符的一种,需要符合规范,通常类名的第一个字母大写,且不能有下划线,如果有多个单词则使用驼峰标识。在对方法进行类的划分中,一般采取的做法是谁最熟悉这个方法那么就把这个方法划分给谁。在OC中,对象对方法的调用称为消息机制,即向既定的对象发送了什么消息。

(二)简单内存分析

类创建对象,每个对象在内存中都占据一定的存储空间,每个对象都有一份属于自己的单独的成员变量,所有的对象公用类的成员方法,方法在整个内存中只有一份,类本身在内存中占据一份存储空间,类的方法存储于此。

每个对象内部都默认有一个isa指针指向这个对象所使用的类。

[p eat];

表示给p所指向的对象发送一条eat消息,调用对象的eat方法,此时对象会顺着内部的isa指针找到存储于类中的方法,执行。

isa是对象中的隐藏指针,指向创建这个对象的类。

(三)类的声明和实现

1)类的声明:

这里声明了一个Person类,这个类拥有一个@public修饰的属性(成员变量),以及一个对象方法put

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# import <Foundation/Foundation.h>

@interface Person : NSObject
{
	@public
	int _age;
}

- (void)put;

@end
2)类的实现:

类的实现可以理解为类中的方法的实现

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# import "Person.h"

@implementation Person

- (void)put
  {
    NSLog(@"第一个程序!");
  }

@end
3)类的调用:

在主函数首先创建了一个Person类型的对象(先调用alloc分配存储空间,后调用init方法初始化为0),并定义了一个Person类型的指针指向创建的这个对象,之后初始化对象成员变量_age的值为20,然后调用了对象的put方法,打印输出。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
# import <UIKit/UIKit.h>

# import "AppDelegate.h"

# import "Person.h"

int main(int argc, char * argv[]) {
	@autoreleasepool {

        Person *penson = [[Person alloc] init];
        penson->_age = 20;
        [penson put];
        NSLog(@"怎么那么美!");

        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
	}
}

//打印结果
2016-05-28 12:04:44.640 test[20234:2570081] 第一个程序!
2016-05-28 12:04:44.641 test[20234:2570081] 怎么那么美!
4)练习,创建一个Person类。

类的声明:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# import <Foundation/Foundation.h>

@interface Person : NSObject
{
    @public
    int _age;
    int _weight;

}

- (void)walk;

@end

类的实现如下:

1
2
3
4
5
6
7
8
9
# import "Person.h"

@implementation Person

- (void)walk {
  NSLog(@"%d岁, %d千克的人, 走了一段路!", self->_age, self->_weight);
  }

@end

类的调用如下:

 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
# import <UIKit/UIKit.h>

# import "AppDelegate.h"

# import "Person.h"

int main(int argc, char * argv[]) {
    @autoreleasepool {
        Person *p1 = [[Person alloc] init];
        p1->_age = 10;
        p1->_weight = 50;
        [p1 walk];

        Person *p3 = p1;
        p3->_age = 11;
        [p3 walk];
        [p1 walk];

        Person *p2 = [[Person alloc] init];
        p2->_weight = 40;
        p2->_age = 40;
        [p2 walk];

        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
	}
}

//打印结果
2016-05-28 12:13:40.795 test[20255:2595399] 10, 50千克的人, 走了一段路!
2016-05-28 12:13:40.796 test[20255:2595399] 11, 50千克的人, 走了一段路!
2016-05-28 12:13:40.797 test[20255:2595399] 11, 50千克的人, 走了一段路!
2016-05-28 12:13:40.797 test[20255:2595399] 40, 40千克的人, 走了一段路!

(四)常见错误

  1. @interface @end@implementation  @end 不能嵌套包含
  2. 只有类的声明没有类的实现
  3. 漏写@end
  4. 两个类的声明嵌套(可以把顺序打乱)
  5. 成员变量没有写在{}里
  6. 方法的声明写在了{}里面
  7. 在声明时对类的成员变量进行初始化,请注意成员变量不能脱离对象而独立存在
  8. 方法无法像函数那样的调用
  9. 成员变量和方法不能用static等关键字修饰,不要和c语言混淆
  10. 类的实现可以写在mian函数后面,在使用之前只要有声明就可以

三、OC对象与函数

OC对象与函数有着本质的区别:
  1. 方法的实现只能写在@implementation··@end中,对象方法的声明只能写在@interface···@end中间
  2. 对象方法都以-号开头,类方法都以+号开头
  3. 对象方法只能由对象来调用,类方法只能由类来调用,不能当做函数一样调用
  4. 函数属于整个文件,可以写在文件中的任何位置,包括@implementation··@end中,但写在@interface···@end会无法识别,函数的声明可以在main函数内部也可以在main函数外部。
  5. 对象方法归类对象所有
  6. 函数调用不依赖与对象
  7. 函数内部不能直接通过成员变量名访问对象的成员变量

四、类和方法的设计

工具类:基本没有任何的成员变量,里面的方法基本都是类方法。

注意:在对象方法中可以调用类方法。

需求:设计一个工具类,一个计算器类,要求(1)返回π,(2)计算两个整数的和,(3)计算某个整数的平方。

类的声明部分:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
#import <Foundation/Foundation.h>

@interface JiSuanQi : NSObject

/// 返回π
- (double)pi;

/// 计算两个整数的和
- (int)SumWithNumber1:(int)num1 Number2:(int)num2;

/// 计算某个整数的平方
- (int)PingFang:(int)number;

@end

类的实现部分:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
#import "JiSuanQi.h"

@implementation JiSuanQi
/// 返回π
- (double)pi {
    return 3.1415926;
}

/// 计算两个整数的和
- (int)SumWithNumber1:(int)num1 Number2:(int)num2 {
    return num1 + num2;
}

/// 计算某个整数的平方
- (int)PingFang:(int)number {
    return number * number;
}

@end

测试程序:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#import <UIKit/UIKit.h>
#import "AppDelegate.h"

#import "JiSuanQi.h"

int main(int argc, char * argv[]) {
	@autoreleasepool {


        JiSuanQi *jisuanqi = [[JiSuanQi alloc] init];
        NSLog(@"%f",[jisuanqi pi]);
        NSLog(@"%d",[jisuanqi SumWithNumber1:2 Number2:3]);
        NSLog(@"%d",[jisuanqi PingFang:4]);


        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
    }
}

//打印结果
2016-05-28 12:37:50.365 test[20296:2661742] 3.141593
2016-05-28 12:37:50.367 test[20296:2661742] 5
2016-05-28 12:37:50.367 test[20296:2661742] 16