-------
Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
一、封装
1、什么是封装
隐藏对象的属性和实现细节,仅对外公开接口,控制在程序中属性的读和修改的访问级别;将抽象得到的数据和行为(功能)相结合,形成一个有机的整体,也就是将数据与操作数据的源代码进行有机的结合,形成“类”,其中数据和函数都是类的成员。简单点说就是隐藏对象的属性和方法的实现细节,对外只公开接口用来调用2、set方法
在开发过程中,考虑到安全性要求,我们一般不在成员变量名前面使用@public、@protected等关键字修饰,而是使用Set方法来为对象提供成员变量的值。在set方法的内部也可以对一些不合理的赋值进行筛选过滤。
Set方法的作用:为外界提供一个设置成员变量值的方法。
命名规范:
(1)方法名必须以set开头
(2)Set后面跟上成员变量的名称,首字母大写
(3)返回值一定是void
(4)一定要接收一个参数,而且参数类型需要和成员变量的类型一致
(5)形参名不能喝成员变量名一样(苹果官方推荐成员变量名前加_以示区分)
Set方法的好处:
(1)不让数据暴露在外,保证了数据的安全性
(2)对设置的数据进行过滤
Set方法使用示例:
Set方法的声明:
#import <Foundation/Foundation.h>
@interface Student : NSObject
{
// @public
int _age;
}
// 提供一个方法给外接设置age属性值
- (void) setAge:(int)age;
// 学习方法
- (void)study;
@end
Set方法的实现:
@implementation Student
- (void)study
{
NSLog(@"一个%d岁的学生正在学习!", age);
}
- (void)setAge:(int)age
{
// 对传进来的参数进行过滤
if (age <= 0){
age = 0;
}
_age = age;
}
@end
测试程序:
int main(int argc, const char *argv[])
{
Student *stu = [Student new];
// stu->_age = 10;
[stu setAge:10];
[stu study];
return 0;
}
运行结果:
MyMac:0805 rui$ cc 01-封装.m -framework Foundation
MyMac:0805 rui$ ./a.out
2015-04-02 17:15:24.145 a.out[1243:140004] 一个10岁的学生正在学习
3、get方法
Get方法的作用:为调用者返回对象内部的成员变量
命名规范:
(1)一定有返回值,返回值的类型和成员变量的类型一致
(2)方法名和成员变量名一样
(3)不需要接收任何参数
Get方法使用示例:
get方法的声明:
#import <Foundation/Foundation.h>
@interface Student : NSObject
{
// @public
int _age;
}
// 提供一个方法给外接设置age属性值
- (void) setAge:(int)age;
// 提供一个查询属性_age的方法
- (int) age;
// 学习方法
- (void)study;
@end
get方法的实现:
implementation Student
- (void)study
{
NSLog(@"一个%d岁的学生正在学习!", _age);
}
- (void)setAge:(int)age
{
// 对传进来的参数进行过滤
if (age <= 0){
age = 0;
}
_age = age;
}
- (int)age
{
return _age;
}
@end
测试程序:
nt main(int argc, const char *argv[])
{
Student *stu = [Student new];
// stu->_age = 10;
[stu setAge:10];
// [stu study];
NSLog(@"学生的年纪是:%d", [stu age]);
return 0;
}
测试结果:
MyMac:0805 rui$ ./a.out
2015-04-02 17:21:50.409 a.out[1247:142575] 学生的年纪是:10
注意1:在实际的开发中,不一定set和get方法都会提供,如果内部的成员变量比如学生的学号这样的数据只允许外界读取,但是不允许修改的情况,则通常只提供get方法而不提供set方法。
注意2:成员变量名的命名以下划线开头,get方法名不需要带下划线,使用下划线开头有两个好处:(1)与get方法的方法名区分开来;(2)可以喝一些其他的局部变量区分开来,下划线开头的变量,通常都是类的成员变量。
4、set和get方法综合使用
/*
设计一个成绩类
* C语言成绩(可读可写)
* OC成绩(可读可写)
* 总分(只读)
* 平均分(只读)
*/
#import <Foundation/Foundation.h>
@interface Score : NSObject
{
double _cScore; // C语言成绩
double _ocScore; // OC语言成绩
double _totalScore; // 总分
double _avrgScore; // 平均分
}
- (void)setCScore:(double)cScore;
- (double)cScore;
- (void)setOCScore:(double)ocScore;
- (double)ocScore;
- (double)totalScore;
- (double)avrgScore;
@end
@implementation Score
- (void)setCScore:(double)cScore
{
_cScore = cScore;
}
- (double)cScore
{
return _cScore;
}
- (void)setOCScore:(double)ocScore
{
_ocScore = ocScore;
}
- (double)ocScore
{
return _ocScore;
}
- (double)totalScore
{
_totalScore = _cScore + _ocScore;
return _totalScore;
}
- (double)avrgScore
{
_totalScore = _cScore + _ocScore;
_avrgScore = _totalScore / 2;
return _avrgScore;
}
@end
int main(int argc, const char *argv[])
{
Score *s = [Score new];
[s setCScore:90];
[s setOCScore:92];
NSLog(@"总分为:%f,平均分为:%f", [s totalScore], [s avrgScore]);
return 0;
}
二、类方法
每一个类都会实例一个对象,从而这个对象可以完成某些行为,这些行为就是对象方法,类也有方法,叫做类方法。当我们创建一个对象的时候就已经用到了类方法。例如:Student *s=[Student new] 这句代码中创建了一个Student类型的新对象s,而[Student new]是利用类Student 调用了类方法中的new方法,完成创建对象的方法。new方法存在于父类 NSObject 中定义。
1、基本概念
直接可以用类名来执行的方法(类本身会在内存中占据存储空间,里面有类\对象方法列表)
2、对象方法
·以减号-开头
·只能让对象调用,没有对象,这个方法根本不可能被执行
·对象方法能访问实例变量(成员变量)
·只能让对象调用,没有对象,这个方法根本不可能被执行
·对象方法能访问实例变量(成员变量)
#import <Foundation/Foundation.h>
@interface Person : NSObject
{
int _age; // 人的年龄属性
}
// 对象的方法,以 - 开头
- (void)setAge:(int)age;
- (int)age;
// 类的方法,以 + 开头
+ (void)printClassName;
@end
3、类方法
·以加号+开头·只能用类名调用,对象不能调用
·类方法中不能访问实例变量(成员变量)
·使用场合:当不需要访问成员变量的时候,尽量用类方法
#import <Foundation/Foundation.h>
@interface Person : NSObject
{
int _age; // 人的年龄属性
}
// 对象的方法,以 - 开头
- (void)setAge:(int)age;
- (int)age;
- (void)printClassName;
// 类的方法,以 + 开头
+ (void)printClassName;
@end
4、类方法和对象方法可以同名
- (void)printClassName;
// 类的方法,以 + 开头
+ (void)printClassName;
5、类方法和对象方法的实现
#import <Foundation/Foundation.h>
@interface Person : NSObject
{
int _age; // 人的年龄属性
}
// 对象的方法,以 - 开头
- (void)setAge:(int)age;
- (int)age;
- (void)printClassName;
// 类的方法,以 + 开头
+ (void)printClassName;
@end
6、测试运行
int main(int argc, const char *argv[])
{
Person *p = [Person new];
[p setAge:23];
NSLog(@"人的年龄是%d", [p age]);
[p printClassName];
[Person printClassName];
return 0;
}
运行结果:
2015-04-02 19:25:33.339 a.out[1433:176195] 人的年龄是23
2015-04-02 19:25:33.341 a.out[1433:176195] 对象方法printClassName!
2015-04-02 19:25:33.341 a.out[1433:176195] 类方法printClassName!
7、实例
设计一个计算器类
*求和
*求平均值
*/
#import <Foundation/Foundation.h>
@interface Caculator : NSObject
// 对象方法,求和
- (int)sumOfNum1:(int)num1 andNum2:(int)num2;
// 对象方法,求平均值
- (int)averageOfNum1:(int)num1 andNum2:(int)num2;
// 类方法,求和
+ (int)sumOfNum1:(int)num1 andNum2:(int)num2;
// 类方法,求平均值
+ (int)averageOfNum1:(int)num1 andNum2:(int)num2;
@end
@implementation Caculator
// 对象方法,求和
- (int)sumOfNum1:(int)num1 andNum2:(int)num2
{
return num1 + num2;
}
// 对象方法,求平均值
- (int)averageOfNum1:(int)num1 andNum2:(int)num2
{
return (num1 + num2) / 2;
}
// 类方法,求和
+ (int)sumOfNum1:(int)num1 andNum2:(int)num2
{
return num1 + num2;
}
// 类方法,求平均值
+ (int)averageOfNum1:(int)num1 andNum2:(int)num2
{
return [Caculator sumOfNum1:num1 andNum2:num2]/ 2;
}
@end
int main(int argc, const char *argv[])
{
int num1 = 10;
int num2 = 20;
Caculator *c = [Caculator new];
int sum1 = [c sumOfNum1:num1 andNum2:num2];
int avrg1 = [c averageOfNum1:num1 andNum2:num2];
int sum2 = [Caculator sumOfNum1:num1 andNum2:num2];
int avrg2 = [Caculator averageOfNum1:num1 andNum2:num2];
NSLog(@"对象方法:%d与%d的和为%d", num1, num2, sum1);
NSLog(@"类方法:%d与%d的和为%d", num1, num2, sum2);
NSLog(@"对象方法:%d与%d的平均值为%d", num1, num2, avrg1);
NSLog(@"类方法:%d与%d的平均值为%d", num1, num2, avrg2);
return 0;
}
测试运行:
2015-04-02 19:51:25.687 a.out[1505:183651] 对象方法:10与20的和为30
2015-04-02 19:51:25.688 a.out[1505:183651] 类方法:10与20的和为30
2015-04-02 19:51:25.688 a.out[1505:183651] 对象方法:10与20的平均值为15
2015-04-02 19:51:25.689 a.out[1505:183651] 类方法:10与20的平均值为15