一、面向对象的三大特性:封装(成员变量)、继承和多态
1、 set方法和get方法
1. set方法和get方法的使用场合

@public的成员可以被随意赋值,应该使用set方法和get方法来管理成员的访问(类似机场的安检、水龙头过滤,过滤掉不合理的东西),比如僵尸的生命值不能为负数

2. set方法
1) 作用:用来设置成员变量,可以在方法里面过滤掉一些不合理的值
2) 命名规范:
➢ 方法都是以set开头,而且后面跟上成员变量名,成员变量名的首字母必须大写
➢ 形参名称不要跟成员变量同名
3. get方法
1) 作用:返回对象内部的成员变量
2) 命名规范:get方法的名称一般就跟成员变量同名
4. 成员变量的命名规范
➢ 成员变量都以下划线 _ 开头
➢ 可以跟get方法的名称区分开
➢ 可以跟其他局部变量区分开,一看到下划线开头的变量,肯定是成员变量
5. 代码示例

#import <Foundation/Foundation.h>

// 声明

@interface Car : NSObject

{

int _wheels; // 轮子个数

}

/*set方法*/

- (void) setWheels:(int)wheels;

/*get方法*/

- (int) wheels;

@end

@implementation Car

// set方法的实现

- (void) setWheels:(int)wheels

{

// 对外面传进来的轮子数进行过滤

if (wheels<=0)

{

wheels = 1;

}

_wheels = wheels;

}

// get方法的实现

- (int) wheels

{

return _wheels;

}

@end

6. 封装的好处
➢ 过滤不合理的值
➢ 屏蔽内部的赋值过程
➢ 让外界不必关注内部的细节
 
 /**
4.设计Car类
1> 属性
* 速度 2> 方法
* 属性相应的set和get方法
* 一个对象方法跟其他车子比较车速,返回速度差
* 一个类方法比较两辆车的车速,返回速度差
*/ #import <Foundation/Foundation.h> // 车
@interface Car : NSObject
{
int _speed; // 速度
} // 速度的getter和setter
- (void)setSpeed:(int)speed;
- (int)speed; // 跟其他车子比较车速,返回速度差
- (int)compareSpeedWithOther:(Car *)car;
// 比较两辆车的车速,返回速度差
+ (int)compareSpeedBetweenCar1:(Car *)car1 andCar2:(Car *)car2;
@end @implementation Car
// 速度的getter和setter
- (void)setSpeed:(int)speed
{
_speed = speed;
}
- (int)speed
{
return _speed;
} // 跟其他车子比较车速,返回速度差
- (int)compareSpeedWithOther:(Car *)car
{
// 第1种思路
// return _speed - [car speed]; // 第2种思路
return [Car compareSpeedBetweenCar1:self andCar2:car];
} // 比较两辆车的车速,返回速度差
+ (int)compareSpeedBetweenCar1:(Car *)car1 andCar2:(Car *)car2
{
return [car1 speed] - [car2 speed];
}
@end
2、 类方法
1. 基本概念

直接可以用类名来执行的方法(类本身会在内存中占据存储空间,里面有类\对象方法列表)

2. 类方法和对象方法对比
1) 对象方法
➢ 以减号-开头
➢ 只能让对象调用,没有对象,这个方法根本不可能被执行
➢ 对象方法能访问实例变量(成员变量)
2) 类方法
➢ 以加号+开头
➢ 只能用类名调用,对象不能调用
➢ 类方法中不能访问实例变量(成员变量)
➢ 使用场合:当不需要访问成员变量的时候,尽量用类方法
3) 类方法和对象方法可以同名
 
3、 self关键字
1. 成员变量和局部变量同名
➢ 当成员变量和局部变量同名时,采取就近原则,访问的是局部变量
➢ 用self访问成员变量,区分同名的局部变量
2. 使用细节
1) 出现的地方:所有的OC方法中(对象方法\类方法),不能出现在函数
2) 作用
➢ 使用 "self->成员变量名" 访问当前方法调用的成员变量
➢ 使用 "[self 方法名];" 来调用方法(对象方法\类方法)
3. 常见错误
➢ 低级错误:用self去调用函数
➢ 类方法中用self调用对象方法,对象方法中用self调用类方法
➢ self死循环
 

练习:设计一个成绩类

* C语言成绩(可读可写)

* OC成绩(可读可写)

* 总分(只读)

* 平均分(只读)

 #import <Foundation/Foundation.h>

 @interface Score : NSObject
{
int _cScore; // C语言成绩
int _ocScore; // OC成绩 int _totalScore;// 总分
int _averageScoe; // 平均分
} - (void)setCScore:(int)cScore;
- (int)cScore; - (void)setOcScore:(int)ocScore;
- (int)ocScore; - (int)totalScore;
- (int)averageScore; @end @implementation Score
- (void)setCScore:(int)cScore
{
_cScore = cScore; // 计算总分
_totalScore = _cScore + _ocScore;
_averageScoe = _totalScore/;
}
- (int)cScore
{
return _cScore;
} - (void)setOcScore:(int)ocScore
{
_ocScore = ocScore; // 计算总分
_totalScore = _cScore + _ocScore;
_averageScoe = _totalScore/;
}
// 监听成员变量的改变 - (int)ocScore
{
return _ocScore;
} - (int)totalScore
{
return _totalScore;
}
- (int)averageScore
{
return _averageScoe;
}
@end int main()
{
Score *s = [Score new]; [s setCScore:];
[s setOcScore:]; [s setCScore:]; int a = [s totalScore]; NSLog(@"总分:%d", a);
二、 继承
1. 继承的基本用法
● 设计两个类Bird、Dog

// Bird的声明

@interface Bird : NSObject

{

@public

int weight;

}

- (void)eat;

@end

// Bird的定义

@implementation Bird

- (void)eat {

NSLog(@"吃吃吃-体重:%d", weight);

}

@end

// Dog的声明

@interface Dog : NSObject

{

@public

int weight;

}

- (void)eat;

@end

// Dog的定义

@implementation Dog

- (void)eat {

NSLog(@"吃吃吃-体重:%d", weight);

}

@end

● 有相同的属性和行为,抽出一个父类Animal(先抽取weight属性,再抽取eat方法)

// Animal的声明

@interface Animal : NSObject

{

@public

int weight;

}

- (void)eat;

@end

// Animal的定义

@implementation Animal

- (void)eat {

NSLog(@"吃吃吃-体重:%d", weight);

}

@end

● 子类在父类的基础上拓充属性和方法

// Bird的声明

@interface Bird : Animal

{

@public

int height;

}

- (void)fly;

@end

// Bird的定义

@implementation Bird

- (void)fly {

NSLog(@"飞飞飞-高度:%d", height);

}

@end

// Dog的声明

@interface Dog : Animal

{

@public

int speed;

}

- (void)run;

@end

// Dog的定义

@implementation Dog

- (void)run {

NSLog(@"跑跑跑-高度:%d", speed);

}

@end

● 子类方法和属性的访问过程:如果子类没有,就去访问父类的
● 父类被继承了还是能照常使用的
● 父类的静态方法
● 画继承结构图,从子类抽取到父类
● NSObject的引出:全部OC类的最终父类,包含了一些常用方法,比如+new
2. 继承的专业术语
● 父类\超类  superclass
● 子类  subclass\subclasses
3. 继承的细节
● 单继承
● 子类和父类不能有相同的成员变量
● 方法的重写
4. super关键字
● 分别调用父类的对象方法和类方法

在子类中重写方法时,可以让调用者跳过这一层而调用父类中的方法。

 /*
僵尸 跳跃僵尸、舞王僵尸、铁桶僵尸
*/
#import <Foundation/Foundation.h> /*
super的作用
1.直接调用父类中的某个方法
2.super处在对象方法中,那么就会调用父类的对象方法
super处在类方法中,那么就会调用父类的类方法 3.使用场合:子类重写父类的方法时想保留父类的一些行为
*/ // 僵尸
@interface Zoombie : NSObject
- (void)walk; + (void)test;
- (void)test; @end @implementation Zoombie
- (void)walk
{
NSLog(@"往前挪两步******");
} + (void)test
{
NSLog(@"Zoombie+test");
} - (void)test
{
NSLog(@"Zoombie-test");
}
@end // 跳跃僵尸
@interface JumpZoombie : Zoombie
+ (void)haha;
- (void)haha2;
@end @implementation JumpZoombie + (void)haha
{
[super test];
} - (void)haha2
{
[super test];
} - (void)walk
{
// 跳两下
NSLog(@"跳两下"); // 走两下(直接调用父类的walk方法)
[super walk];
//NSLog(@"往前挪两步----"); }
@end int main()
{
//[JumpZoombie haha];
JumpZoombie *jz = [JumpZoombie new]; [jz walk]; return ;
}

5. 继承的好处

● 不改变原来模型的基础上,拓充方法
● 建立了类与类之间的联系
● 抽取了公共代码
● 坏处:耦合性强
6. 继承的使用场合
● 它的所有属性都是你想要的,一般就继承
● 它的部分属性是你想要的,可以抽取出另一个父类
继承的使用场合练习

1> 当两个类拥有相同属性和方法的时候,就可以将相同的东西抽取到一个父类中

2> 当A类完全拥有B类中的部分属性和方法时,可以考虑让B类继承A类

A

{

int _age;

int _no;

}

B : A

{

int _weight;

}

// 继承:xx 是 xxx

// 组合:xxx 拥有 xxx

2.组合

A

{

int _age;

int _no;

}

B

{

A *_a;

int _weight;

}

 
 #import <Foundation/Foundation.h>
/*
1.继承的好处:
1> 抽取重复代码
2> 建立了类之间的关系
3> 子类可以拥有父类中的所有成员变量和方法 2.注意点
1> 基本上所有类的根类是NSObject
*/ /********Animal的声明*******/
@interface Animal : NSObject
{
int _age;
double _weight;
} - (void)setAge:(int)age;
- (int)age; - (void)setWeight:(double)weight;
- (double)weight;
@end /********Animal的实现*******/
@implementation Animal
- (void)setAge:(int)age
{
_age = age;
}
- (int)age
{
return _age;
} - (void)setWeight:(double)weight
{
_weight = weight;
}
- (double)weight
{
return _weight;
}
@end /********Dog*******/
// : Animal 继承了Animal,相当于拥有了Animal里面的所有成员变量和方法
// Animal称为Dog的父类
// Dog称为Animal的子类
@interface Dog : Animal
@end @implementation Dog
@end /********Cat*******/
@interface Cat : Animal
@end @implementation Cat
@end int main()
{
Dog *d = [Dog new]; [d setAge:]; NSLog(@"age=%d", [d age]);
return ;
}
三、多态
 
1. 多态的基本概念
● 某一类事物的多种形态,必须要有继承,没有继承就没有多态。
● OC对象具有多态性,多态在代码中的体现即父类指针指向子类对象。
2. 多态的体现

Person *p = [Student new];

p->age = 100;

[p walk];

● 子类对象赋值给父类指针
● 父类指针访问对应的属性和方法
3. 多态的好处
● 用父类接收参数,节省代码
4. 多态的局限性
● 不能访问子类的属性(可以考虑强制转换)
5. 多态的细节
● 动态绑定:在运行时根据对象的类型确定动态调用的方法
 

多态使用总结

1.没有继承就没有多态

2.代码的体现:父类类型的指针指向子类对象

3.好处:如果函数\方法参数中使用的是父类类型,可以传入父类、子类对象

4.局限性: 父类类型的变量不能直接调用子类特有的方法。必须强转为子类类型变量后,才能直接调用子类特有的方法

 #import <Foundation/Foundation.h>
// 动物
@interface Animal : NSObject
- (void)eat;
@end @implementation Animal
- (void)eat
{
NSLog(@"Animal-吃东西----");
}
@end // 狗
@interface Dog : Animal
- (void)run;
@end @implementation Dog
- (void)run
{
NSLog(@"Dog---跑起来");
}
- (void)eat
{
NSLog(@"Dog-吃东西----");
}
@end // 猫
@interface Cat : Animal @end @implementation Cat
- (void)eat
{
NSLog(@"Cat-吃东西----");
}
@end // 这个函数是专门用来喂动画
//void feed(Dog *d)
//{
// [d eat];
//}
//
//void feed2(Cat *c)
//{
// [c eat];
//}
// // 如果参数中使用的是父类类型,可以传入父类、子类对象
void feed(Animal *a)
{
[a eat];
} int main()
{
// 多态的局限性:父类类型的变量 不能 用来调用子类的方法
Animal *aa = [Animal new];
feed(aa); Dog *dd = [Dog new];
feed(dd); Cat *cc = [Cat new];
feed(cc); // NSString *s = [Cat new];
Animal *c = [Cat new]; NSObject *n = [Dog new];
NSObject *n2 = [Animal new]; //多种形态
Dog *d = [Dog new]; // Dog类型 //多态:父类指针指向子类对象
Animal *a = [Dog new]; // 调用方法时会检测对象的真实形象
[a eat]; return ;
}
3、 NSString的简单使用
 
1. 字符串的快速创建

NSStirng *str = @“Hello”;

2. 使用静态方法创建
3. 使用%@输出字符串

NSString *name = @”mj”;

NSLog(@“我的名字是%@”,  name);

 #import <Foundation/Foundation.h>

 @interface Person : NSObject
{
//char *_name;
NSString *_name;
}
@end int main()
{
/*
// 最简单的创建字符串的方式
NSString *str = @"itcast"; char *name = "itcast"; NSLog(@"我在%@上课", str);
//NSLog(@"%s", name);
*/ int age = ;
int no = ;
NSString *name = @"哈哈jack";
// length方法算的是字数
int size = [name length]; NSLog(@"%d", size); // 创建OC字符串的另一种方式
NSString *newStr = [NSString stringWithFormat:@"My age is %d and no is %d and name is %@", age, no, name]; NSLog(@"---- %ld", [newStr length]); return ;
}

作业

 /**
6.设计一个类Circle,用来表示二维平面中的圆
1> 属性
* double radius (半径)
* Point2D *point (圆心) 2> 方法
* 属性相应的set和get方法
* 设计一个对象方法判断跟其他圆是否相交(重叠返回YES,否则返回NO)
* 设计一个类方法判断两个圆是否相交(重叠返回YES,否则返回NO)
*/
#import <Foundation/Foundation.h>
#import <math.h> // 点
@interface Point2D : NSObject
{
double _x; // x值
double _y; // y值
}
// x值的getter和setter
- (void)setX:(double)x;
- (double)x; // y值的getter和setter
- (void)setY:(double)y;
- (double)y; // 同时设置x和y
- (void)setX:(double)x andY:(double)y; // 计算跟其他点的距离
- (double)distanceWithOther:(Point2D *)other; // 计算两个点之间的距离
+ (double)distanceBetweenPoint1:(Point2D *)p1 andPoint2:(Point2D *)p2;
@end @implementation Point2D
// x值的getter和setter
- (void)setX:(double)x
{
_x = x;
}
- (double)x
{
return _x;
} // y值的getter和setter
- (void)setY:(double)y
{
_y = y;
}
- (double)y
{
return _y;
} // 同时设置x和y
- (void)setX:(double)x andY:(double)y
{
// 第1种思路
// _x = x;
// _y = y; // 第2种思路
[self setX:x];
[self setY:y];
} // 计算跟其他点的距离
- (double)distanceWithOther:(Point2D *)other
{
// 不要再傻乎乎算一遍了,直接调用类方法即可
return [Point2D distanceBetweenPoint1:self andPoint2:other];
} // 计算两个点之间的距离
+ (double)distanceBetweenPoint1:(Point2D *)p1 andPoint2:(Point2D *)p2
{
// 两点距离公式:( (x1-x2)的平方 + (y1-y2)的平方 )开根 // x1-x2
double xDelta = [p1 x] - [p2 x];
// (x1-x2)的平方
double xDeltaPingFang = pow(xDelta, ); // y1-y2
double yDelta = [p1 y] - [p2 y];
// (y1-y2)的平方
double yDeltaPingFang = pow(yDelta, ); return sqrt(xDeltaPingFang + yDeltaPingFang);
}
@end // 圆
@interface Circle : NSObject
{
double _radius; // 半径
Point2D *_point; // 圆心
} // 半径的getter和setter
- (void)setRadius:(double)radius;
- (double)radius; // 圆心的getter和setter
- (void)setPoint:(Point2D *)point;
- (Point2D *)point; // 跟其他圆是否重叠(重叠返回YES,否则返回NO)
- (BOOL)isInteractWithOther:(Circle *)other;
// 判断两个圆是否重叠(重叠返回YES,否则返回NO)
+ (BOOL)isInteractBetweenCircle1:(Circle *)circle1 andCircle2:(Circle *)circle2; @end @implementation Circle
// 半径的getter和setter
- (void)setRadius:(double)radius
{
_radius = radius;
}
- (double)radius
{
return _radius;
} // 圆心的getter和setter
- (void)setPoint:(Point2D *)point
{
_point = point;
}
- (Point2D *)point
{
return _point;
} // 跟其他圆是否重叠(重叠返回YES,否则返回NO)
- (BOOL)isInteractWithOther:(Circle *)other
{
return [Circle isInteractBetweenCircle1:self andCircle2:other];
} // 判断两个圆是否重叠(重叠返回YES,否则返回NO)
+ (BOOL)isInteractBetweenCircle1:(Circle *)circle1 andCircle2:(Circle *)circle2
{
// 如果两个圆心的距离 >= 两个圆的半径和,就不重叠
// 如果两个圆心的距离 < 两个圆的半径和,就重叠 // 两个圆心
Point2D *point1 = [circle1 point];
Point2D *point2 = [circle2 point];
// 两个圆心的距离
double distance = [point1 distanceWithOther:point2]; // 半径和
double radiusSum = [circle1 radius] + [circle2 radius]; return distance < radiusSum;
}
@end int main()
{
Circle *c1 = [Circle new];
// 设置半径
[c1 setRadius:];
// 设置圆心
Point2D *p1 = [Point2D new];
[p1 setX: andY:];
[c1 setPoint:p1]; Circle *c2 = [Circle new];
// 设置半径
[c2 setRadius:];
// 设置圆心
Point2D *p2 = [Point2D new];
[p2 setX: andY:];
[c2 setPoint:p2]; // 圆心距离是5 半径和是4 所以不重叠
BOOL b1 = [c1 isInteractWithOther:c2]; BOOL b2 = [Circle isInteractBetweenCircle1:c1 andCircle2:c2]; NSLog(@"%d %d", b1, b2); return ;
}

OC面向对象的三大特性的更多相关文章

  1. oc语言--面向对象的三大特性

    一.封装 1.什么是封装 在程序上,隐藏对象的属性和实现细节,仅对外公开接口,控制在程序中属性的读和修改的访问级别:将对象得到的数据和行为(或功能)相结合,形成一个有机的整体,也就是将数据与操作数据的 ...

  2. 谈谈Java面向对象的三大特性

    Java面向对象的三大特性就是指封装.继承.多态了. 一.封装: 概念:封装是指隐藏对象的属性和实现细节,仅对外提供公共访问方式. (举例:笔记本电脑就是一个封装体,Java语言中最小的封装体就是函数 ...

  3. OC面向对象的三大特征

    OC面向对象的三大特征 1.OC面向对象的三大特封装 1)封装:完整的说是成员变量的封装. 2)在成语方法里面的成员变量最好不要使用@public这样会直接暴露在外面被别人随随便便修改,封装的方法还可 ...

  4. java基础笔记(6)----面向对象的三大特性

    简介:面向对象的三大特性就是封装,继承,多态,是面向对象的核心. 封装 简介:封装是类的边界,可以对数据起到保护作用 特性:属性私有,提供公开的get/set方法 属性私有:private 数据类型 ...

  5. C#基础知识之面向对象以及面向对象的三大特性

    在C#基础知识之类和结构体中我详细记录了类.类成员.重载.重写.继承等知识总结.这里就记录一下对面向对象和面向对象三大特性的广义理解. 一.理解面向对象 类是面向对象编程的基本单元,面向对象思想其实就 ...

  6. Python面向对象3:面向对象的三大特性

    面向对象的三大特性- 封装- 继承- 多态1 封装 - 封装就是对对象的成员进行访问限制- 封装的三个级别: - 公开,public - 受保护的,protected - 私有的,private - ...

  7. python 之面向对象的三大特性

    面向对象的三大特性 继承 继承和组合 继承进阶 封装 封装(有待完善) 多态 多态

  8. JavaScript面向对象的三大特性

    1.JavaScript面向对象的三大特性 JavaScript的三大特性:封装性.继承性.多态性. 2.JavaScript实现封装特性 在一些静态类型的语言如java中,本身语法就提供了这些功能. ...

  9. Python 面向对象(创建类和对象,面向对象的三大特性是指:封装、继承和多态,多态性)

    概念:                                                                                                 ...

随机推荐

  1. 如何搭建ftp的yum源

                ftp的yum的搭建步骤 第一步:安装vsftpd程序包(系统已经安装) [root@station40 ~]# rpm -qa |grep vsftpd vsftpd-2.2 ...

  2. Linux入门(8)——Ubuntu16.04安装sublime text 3并配置Python开发环境

    打开终端,添加sublime text 3的仓库: 按enter键继续 更新软件库: sudo apt-get update 安装Sublime Text 3: sudo apt-get instal ...

  3. LINUX 笔记-文本过滤

    ^                        只匹配行首 $                       只匹配行尾 *                        一个单字符后紧跟*,匹配0个 ...

  4. bootstrap select多选

    1.页面效果 <div class="form-group"> <div class="col-md-2 control-label"> ...

  5. How the Intelligent Digital Mesh Will Transform Every Business Layer

    The "intelligent digital mesh" is the definitive package for tomorrow's titans of business ...

  6. 【译】10分钟学会Pandas

    十分钟学会Pandas 这是关于Pandas的简短介绍主要面向新用户.你可以参考Cookbook了解更复杂的使用方法 习惯上,我们这样导入: In [1]: import pandas as pd I ...

  7. json格式转化成map

    public static Map<String, Object> parseJSON2Map(String jsonStr) { Map<String, Object> ma ...

  8. linux学习(五)系统目录结构,ls命令,文件类型,alias

    一.系统目录结构 在我们的根目录下,有这样一些文件夹 /bin /sbin /usr/bin /usr/sbin /sbin一般都是root用户用的 /boot 系统启动相关的,grup就放在这里,这 ...

  9. HTML5 input事件检测输入框变化[转载]

    原文:http://www.linuxidc.com/Linux/2015-07/119984.htm 之前一直用change事件来监听输入框内容是否发生变化,只有当输入框失去焦点时才会触发,没想到h ...

  10. 静态代理设计模式(StaticProxy)

    静态代理设计模式: 要求:真实角色,代理角色:真实角色和代理角色要实现同一个接口,代理角色要持有真实角色的引用. 在Java中线程的设计就使用了静态代理设计模式,其中自定义线程类实现Runable接口 ...