1.面向对象编程5. 面向对象编程
用解决现实中的问题的办法来解决计算机问题。
5.1 对象
Anything is Object. 万物皆对象。
现实中对象是一种客观的存在,程序中对象是一片内存空间。
对象之间各司其职,各尽所能,对象功能单一。对象之间通过发消息来互相合作,形成一个系统。
对象
有什么 属性
能干什么 方法
5.2 类
就是类型,这儿理解为用户自定义的类型。
int double float ... 基本数据类型
TRDate ... 用户自定义类型
类是一种主观的认识,是对我们需要解决的问题的一种抽象,是创建对象的模型。
5.3 定义类
@interface 类名 : NSObject
属性的定义
方法的声明
@end
让类继承NSObject是因为需要类拥有相应的能力,比如内存分配能力等。
@implementation 类名
方法的定义
@end
5.4 创建对象
类名* obj = [类名 alloc];
[obj 消息]; //给对象发消息
对象收到消息会调用方法。方法其实是一种特殊的函数。6. 内存分配
OC中的对象全部放在堆中。 要使用堆中的对象,必须使用指针指向对象。经常把这个指针叫"引用"。要让对象工作,就给对象发消息,如果对象响应消息,就会调用对应的方法。消息是通过引用发的。
堆内存,分配和释放不是自动的,而是由程序控制的。
堆里放的是对象,栈里放的是引用,引用指向了对象。7. 实际开发中类定义的文件分离
一个类,一般会分成两个文件,一个.h,一个.m。
.h文件中定义类的interface部分,.m文件中定义类的implementation部分。类名和文件名应该保持一致。
//以下代码在XCode下编写main.m#import <Foundation/Foundation.h>
@interface MyFirstClass : NSObject //继承NSObject,是所有类的老祖宗,分配内存空间
@Property int prop1; //属性的定义
- (void) method1; //方法的声明
@end//实现部分
@implementation MyFirstClass
- (void) method1
{
NSLog(@"我是一个方法");
}
@end
@interface TRDog : NSObject //狗类
@property NSString *name; //OC语言特有的类型,用户自定义类型需指针
- (void)bark;
@end@impementation TRDog
-(void)bark
{
NSLog(@"%@在旺旺的叫", self.name); //%@打印字符串
}
@endTRDog* getDog()
{
TRDog *dog = [TRDog alloc];
dog.name = @"小Mu";
return dog; //对象在堆中,可以返回
}int main(int argc, const char* argv[])
{
@autoreleasepool{
MyFirstClass *obj = [MyFirstClass alloc]; //对象的创建
[obj method1]; //调用方法
TRDog *dog = [TRDog alloc];
dog.name = @"旺财";
[dog bark];
TRDog *dog2 = getDog();
[dog2 bark];
//[obj release]; //编译器会自动写上
//[dog release];
//[dog2 release];
}
return 0;
}
//重新新建一个文件TREmployee.h,定义一个employee类
#import <Foundation/Foundation.h>
//类的接口部分
@interface TREmployee : NSObject
//定义属性
@property NSString *name;
@property int age;
@property BOOL gender;
@property double salary;
//声明部分
- (void) show;
@end//新建一个文件TREmployee.m,写implementation部分
#import "TREmployee.h" //需import
@implementation TREmployee
- (void) show
{
NSLog(@"%@,%@,%d,%.2lf", self.name, self.gender?@"男":"女", self.age, self.salary);
}
@end//main.m中:
#import "TREmployee.h"
void test2()
{
TREmployee *e = [TREmployee alloc];
e.name = @"Daniel";
e.age = 30;
e.gender = YES;
e.salary = 123456.78;
[e show];
//[e release];
}int main(int argc, const char* argv[])
{
@autoreleasepool{
test2();
}
return 0;
}
用解决现实中的问题的办法来解决计算机问题。
5.1 对象
Anything is Object. 万物皆对象。
现实中对象是一种客观的存在,程序中对象是一片内存空间。
对象之间各司其职,各尽所能,对象功能单一。对象之间通过发消息来互相合作,形成一个系统。
对象
有什么 属性
能干什么 方法
5.2 类
就是类型,这儿理解为用户自定义的类型。
int double float ... 基本数据类型
TRDate ... 用户自定义类型
类是一种主观的认识,是对我们需要解决的问题的一种抽象,是创建对象的模型。
5.3 定义类
@interface 类名 : NSObject
属性的定义
方法的声明
@end
让类继承NSObject是因为需要类拥有相应的能力,比如内存分配能力等。
@implementation 类名
方法的定义
@end
5.4 创建对象
类名* obj = [类名 alloc];
[obj 消息]; //给对象发消息
对象收到消息会调用方法。方法其实是一种特殊的函数。6. 内存分配
OC中的对象全部放在堆中。 要使用堆中的对象,必须使用指针指向对象。经常把这个指针叫"引用"。要让对象工作,就给对象发消息,如果对象响应消息,就会调用对应的方法。消息是通过引用发的。
堆内存,分配和释放不是自动的,而是由程序控制的。
堆里放的是对象,栈里放的是引用,引用指向了对象。7. 实际开发中类定义的文件分离
一个类,一般会分成两个文件,一个.h,一个.m。
.h文件中定义类的interface部分,.m文件中定义类的implementation部分。类名和文件名应该保持一致。
//以下代码在XCode下编写main.m#import <Foundation/Foundation.h>
@interface MyFirstClass : NSObject //继承NSObject,是所有类的老祖宗,分配内存空间
@Property int prop1; //属性的定义
- (void) method1; //方法的声明
@end//实现部分
@implementation MyFirstClass
- (void) method1
{
NSLog(@"我是一个方法");
}
@end
@interface TRDog : NSObject //狗类
@property NSString *name; //OC语言特有的类型,用户自定义类型需指针
- (void)bark;
@end@impementation TRDog
-(void)bark
{
NSLog(@"%@在旺旺的叫", self.name); //%@打印字符串
}
@endTRDog* getDog()
{
TRDog *dog = [TRDog alloc];
dog.name = @"小Mu";
return dog; //对象在堆中,可以返回
}int main(int argc, const char* argv[])
{
@autoreleasepool{
MyFirstClass *obj = [MyFirstClass alloc]; //对象的创建
[obj method1]; //调用方法
TRDog *dog = [TRDog alloc];
dog.name = @"旺财";
[dog bark];
TRDog *dog2 = getDog();
[dog2 bark];
//[obj release]; //编译器会自动写上
//[dog release];
//[dog2 release];
}
return 0;
}
//重新新建一个文件TREmployee.h,定义一个employee类
#import <Foundation/Foundation.h>
//类的接口部分
@interface TREmployee : NSObject
//定义属性
@property NSString *name;
@property int age;
@property BOOL gender;
@property double salary;
//声明部分
- (void) show;
@end//新建一个文件TREmployee.m,写implementation部分
#import "TREmployee.h" //需import
@implementation TREmployee
- (void) show
{
NSLog(@"%@,%@,%d,%.2lf", self.name, self.gender?@"男":"女", self.age, self.salary);
}
@end//main.m中:
#import "TREmployee.h"
void test2()
{
TREmployee *e = [TREmployee alloc];
e.name = @"Daniel";
e.age = 30;
e.gender = YES;
e.salary = 123456.78;
[e show];
//[e release];
}int main(int argc, const char* argv[])
{
@autoreleasepool{
test2();
}
return 0;
}
解决方案 »
- Xcode中使用boost库链接出错,system_category找不到
- why NSNumber didn't show correct number
- dismissModalViewController 后会导致父视图的位置复原怎么办?
- 急啊!!!关于虚拟机上安装mac os的问题!(小女感激!)
- 我在AppStore上发行了一个程序,请朋友帮测一下,在AppStore中搜mktNus,多提意见。
- ios 提供某种协议,让其他程序来读取数据
- 通过一个GMAIL地址取得对应的头像。。。
- 台湾 欧付宝支付
- iOS 获取本地视频缩略图
- iOS获取线程ID方法?
- ios的状态栏的背景色如何与导航栏一样
- 想学习IOS
就是类中的函数,写法和函数不同
-(返回值类型)方法名; //无参数
-(返回值类型)方法名:(参数类型)参数名; //一个参数
-(返回值类型)方法名:(参数类型)参数1 :(参数类型)参数2 ...; //多个参数
-(返回值类型)部分方法名:(参数类型)参数1 部分方法名:(参数类型)参数2 ... ":"是方法名的一部分。//在TREmployee.h中:
#import <Foundation/Foundation.h>@interface TREmployee : NSObject
@property NSString *name;
@property int age;
@property BOOL gender;
@property double salary;
- (void) show; //无参方法
- (void)raiseSalary: (double) money; //一个参数
- (double) getSlary;
- (NSString*)genderToString; //返回的是一个对象需用*,返回地址,引用(指针)
- (void) changeName: (NSString*) newName; //OC对象传递需用指针,对象不能随便拷贝
- (void)set: (NSString*) newName :(int)newAge; //两个参数
- (void)set: (NSString*) newName :(int)newAge :(BOOL)newGender : (double)newSalary ; //四个参数
//方法名由若干部分组成
- (void)setName: (NSString*)newName andAge: (int)newAge; //部分方法名
- (void)setName: (NSString*)newName
age: (int)newAge
gender:(BOOL)newGender
salary:(double)newSalary;
@end//在TREmployee.m中:
#import "TREmployee.h"
@implementation TREmployee
- (void) show //无参方法
{
NSLog(@"%@, %@, %d, %g", self.name, [self genderToString], self.age, self.salary);
}
- (void)raiseSalary: (double) money //一个参数
{
self.salary += money;
}
- (double) getSlary
{
return self.salary += money;
}
- (NSString*)genderToString //返回的是一个对象需用*,返回地址,引用(指针)
{
return self.gender?@"男":@"女";
}
- (void) changeName: (NSString*) newName //OC对象传递需用指针,对象不能随便拷贝
{
self.name = newName;
}
- (void)set: (NSString*) newName :(int)newAge //两个参数
{
self.name = newName;
self.Age = newAge;
}
- (void)set: (NSString*) newName :(int)newAge :(BOOL)newGender : (double)newSalary
{
self.Name = newName;
self.Age = newAge;
self.Gender = newGender;
self.salary = newSalary;
}
- (void)setName: (NSString*)newName andAge: (int)newAge //部分方法名
{
self.name = newName;
self.Age = newAge;
}
- (void)setName: (NSString*)newName
age: (int)newAge
gender:(BOOL)newGender
salary:(double)newSalary
{
self.name = newName;
self.age = newAge;
self.gender = newGender;
self.salary = newSalary
}
@end//在main.m中:
#import "TREmployee.h"void test1()
{
TREmployee *e = [TREmployee alloc];
[e show];
e.name = @"Daniel";
[e set:@"Daniel" :30];
[e show];
[e raiseSalary:10000];
[e show];
[e set: @"Daniel" :30 :YES :1234567.78];
[e show];
[e changeName: @"Guodh"];
[e show];
[e set:@"Guodenghong" :31 :YES :123456.78];
[e setName:@"Daniel" andAge: 32];
NSLog(@"你的工资是多少:%g", [e getSalary]);
[e setName:@"Daniel" age:30 gender:YES salary:12345]; //部分方法名,最实用
}int main(int argc, const char *argv[])
{
@autoreleasepool {
test1();
}
return 0;
}
2. 实例变量(InstanceVariable)
(一个对象会有自己独特的数据和别的对象不同,这些数据会保存在一些特殊的变量值中,这种变量叫实例变量。类的每个实例(对象)都有一份。)
用一个类,创建出了一个对象,那我们说这个对象就是此类的一个实例。一个类可以有很多的实例。每一个实例都拥有一份和其他实例不同的数据,这些数据保存在实例变量中。
实例变量可以定义在interface部分,也可以定义在implementation部分。3. 属性//
// Student.h
// day02-2
//
//#import <Foundation/Foundation.h>@interface Student : NSObject
{
//实例变量 保存值的
int _age;
char _sex;
float _salary;
}
//給实例变量赋值
//setter 属性名:int age
-(void)setAge:(int)age; //此age为参数
-(int)age;
-(void)setSex:(char)sex;
-(char)sex;
-(void)setSalary:(float)salary;
-(float)salary;
@end
//
// Student.m
// day02-2
//
//#import "Student.h"@implementation Student{
int _level; //声明了一个私有的实例变量(放在.m中的实例变量是私有的)
}
-(void)getLevel{ //声明了一个私有的实例方法(放在.m中的实例变量是私有的)
NSLog(@"getLevel");
}-(void)setAge:(int)age{
_age = age; //属性和实例变量的关系
NSLog(@"调用了setter方法");
}-(int)age{
return _age;
}-(void)setSex:(char)sex{
_sex = sex;
}-(char)sex{
return _sex;
}-(void)setSalary:(float)salary{
_salary = salary;
}-(float)salary{
return _salary;
}@end
//
// main.m
// day02-2
//
//#import <Foundation/Foundation.h>
#import "Student.h"int main(int argc, const char * argv[])
{ @autoreleasepool {
Student* stu = [Student alloc];
//[stu setAge:20];
//NSLog(@"age:%d", [stu getAge]);
//[stu setSex:'M'];
//NSLog(@"sex:%c", [stu getSex]);
//[stu setSalary:6000.1];
//NSLog(@"salary:%.2f", [stu getSalary]);
stu.age = 18; //自动调用setter方法
NSLog(@"age:%d", stu.age); //自动调用getter方法
stu.sex = 'M'; //自动调用setter方法
int sex = stu.sex; //自动调用getter方法
NSLog(@"sex:%c", sex);
stu.salary = 12000.5; //自动调用setter方法
NSLog(@"salary:%.2f", stu.salary); //自动调用getter方法
}
return 0;
}
OC中,属性指提供了getter和(或)setter方法的数据。
@property int numerator; //setNumerator numerator
@property int denominator; //setDenominator denominator
本质上,属性是方法(不是变量),属性的值是由实例变量来保存。 3.1 属性的本质
属性一般由三个部分组成:
1)保存属性值的实例变量
{
实例变量类型 实例变量名
}
2)getter和setter方法的声明
getter方法的方法名和属性名一样,没有参数,返回值类型和属性类型一样。
-(属性的类型)属性名;
setter方法的方法名是"set" +属性名并首字母大写+":"+和属性类型一样的参数。
3)getter和setter方法的实现
setter方法的实现主要是用来给属性赋值的。
getter方法的实现主要是用来读取属性的值。
引用.属性 = 值; ==>会自动调用setter方法
变量 = 引用.属性; ==>会自动调用getter方法
3.2 声明式的属性
1)定义实例变量
2)在interface部分声明属性:
@property 属性类型 属性名;
3)在implementation部分生成具体的方法:
@synthesize 属性名 = 实例变量名;
会自动生成对应的setter和getter方法。
3.3 从iOS5开始,声明式的属性简化如下:
可以不定义实例变量,编译器会生成"_属性名"的实例变量,但在implementation部分,还必须生成具体的方法:
@synthesize 属性名 = _属性名;
3.4 从iOS6开始,声明式属性又简化:
只需要用@property声明属性即可,实例变量和getter,setter方法的具体实现会自动生成,不需要程序员干涉。
如果你不满意编译器生成的部分,可以自己写。
//
// Point2_1.h
// day02-4
// 属性的第1个版本
// Created by tarena on 14-3-18.
// Copyright (c) 2014年 tarena. All rights reserved.
//#import <Foundation/Foundation.h>@interface Point2_1 : NSObject
{
int x;
int y;
}
-(void)setX:(int)newX;
-(int)getX;
-(void)setY:(int)newY;
-(int)getY;@end//
// Point2_1.m
// day02-4
//
// Created by tarena on 14-3-18.
// Copyright (c) 2014年 tarena. All rights reserved.
//#import "Point2_1.h"@implementation Point2_1-(void)setX:(int)newX{
x = newX;
}-(int)getX{
return x;
}-(void)setY:(int)newY{
y = newY;
}-(int)getY{
return y;
}@end
//
// Point2_2.h
// day02-4
// 属性的第2个版本
// Created by tarena on 14-3-18.
// Copyright (c) 2014年 tarena. All rights reserved.
//#import <Foundation/Foundation.h>@interface Point2_2 : NSObject
{
int _x;
int _y;
}
-(void)setX:(int)x;
-(int)getX;
-(void)setY:(int)y;
-(int)getY;
@end
//
// Point2_2.m
// day02-4
//
// Created by tarena on 14-3-18.
// Copyright (c) 2014年 tarena. All rights reserved.
//#import "Point2_2.h"@implementation Point2_2-(void)setX:(int)x{
_x = x;
}-(int)getX{
return _x;
}-(void)setY:(int)y{
_y = y;
}-(int)getY{
return _y;
}@end
//
// Point2_3.h
// day02-4
// 属性的第3个版本
// Created by tarena on 14-3-18.
// Copyright (c) 2014年 tarena. All rights reserved.
//#import <Foundation/Foundation.h>@interface Point2_3 : NSObject
@property int x;
@property int y;
@end
//
// Point2_3.m
// day02-4
//
// Created by tarena on 14-3-18.
// Copyright (c) 2014年 tarena. All rights reserved.
//#import "Point2_3.h"@implementation Point2_3
@synthesize x = _x;
@synthesize y = _y;
@end
//
// Point2_4.h
// day02-4
// 属性的第4个版本
// Created by tarena on 14-3-18.
// Copyright (c) 2014年 tarena. All rights reserved.
//#import <Foundation/Foundation.h>@interface Point2_4 : NSObject
@property int x;
@property int y;
@end
//
// Point2_4.m
// day02-4
//
// Created by tarena on 14-3-18.
// Copyright (c) 2014年 tarena. All rights reserved.
//#import "Point2_4.h"@implementation Point2_4@end//
// main.m
// day02-4
//
// Created by tarena on 14-3-18.
// Copyright (c) 2014年 tarena. All rights reserved.
//#import <Foundation/Foundation.h>
#import "Point2_1.h"
#import "Point2_2.h"
#import "Point2_3.h"
#import "Point2_4.h"int main(int argc, const char * argv[])
{ @autoreleasepool {
Point2_1* p1 = [Point2_1 alloc];
[p1 setX:10];
[p1 setY:20];
NSLog(@"p1:(%d,%d)", [p1 getX], [p1 getY]);
Point2_2* p2 = [Point2_2 alloc];
[p2 setX:11];
[p2 setY:21];
NSLog(@"p2:(%d,%d)", [p2 getX], [p2 getY]);
Point2_3* p3 = [Point2_3 alloc];
p3.x = 31;
p3.y = 23;
NSLog(@"p3:(%d,%d)", p3.x, p3.y);
Point2_4* p4 = [Point2_4 alloc];
p4.x = 41;
p4.y = 14;
NSLog(@"p4:(%d,%d)", p4.x, p4.y);
}
return 0;
}