一、面向对象的三大特性:封装(成员变量)、继承和多态
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. vim下单行长文本的时候卡顿解决办法

    在vim编辑文件时,若单行过长,可能会导致vim卡顿,严重影响使用体验 估计是syntax匹配效率过滥导致.. 偶尔发现了一个临时的解决办法就是关掉syntax然后再打开,即在命令模式下 :synta ...

  2. 转:C++学习之Pair

    Pair类型概述 pair是一种模板类型,其中包含两个数据值,两个数据的类型可以不同,基本的定义如下: pair<int, string> a; 表示a中有两个类型,第一个元素是int型的 ...

  3. PyCharm 2017 官网 下载 安装 设置 配置 (主题 字体 字号) 使用 入门 教程

    一.安装 Python 3.6 首先,要安装好 Python 3.6.如果你还没有安装,可以参考咪博士之前的教程 Python 3.6.3 官网 下载 安装 测试 入门教程 (windows) 二.官 ...

  4. Vue 国际化 vue-i18n 用法详解

    vue-i18n 仓库地址:https://github.com/kazupon/vue-i18n 兼容性: 支持 Vue.js 2.x 以上版本 安装方法:(此处只演示 npm) npm insta ...

  5. Linux系统挂载操作mount详解

    在Linux系统中,文件系统不挂载是无法使用的.挂载,即是让文件系统在操作系统中可用.在Linux中使用mount命令来挂载文件系统,有永久性挂载和临时性挂载两种挂载方式. 1. 永久性挂载: 修改配 ...

  6. 版本控制之一:SVN服务器搭建与安装(转)

    Subversion是优秀的版本控制工具,其具体的的优点和详细介绍,这里就不再多说. 首先来下载和搭建SVN服务器. 现在Subversion已经迁移到apache网站上了,下载地址: http:// ...

  7. SQL注入技术

    TalkTalk的信息泄漏事件导致约15万人的敏感信息被暴露,涉嫌造成这一事件的其中一名黑客使用的并不是很新的技术.事实上,该技术的「年纪」比这名15岁黑客还要大两岁. [译注:TalkTalk是英国 ...

  8. javascript 可多选的下拉框 multiselect

    首先引用一个写的很好的博客http://www.cnblogs.com/landeanfen/p/5013452.html 我使用的是bootstrap-multiselect,实现功能是 选择下拉框 ...

  9. js 时间字符串转化为时间

    对于时间字符串格式为:"2017-03-03 12:23:55"; IE:显示无效的日期 new Date("2017-03-3 12:23:55") //[d ...

  10. 小米/红米导入VCF联系人乱码问题解决

    PS:尽量不要用什么豌豆荚啊.微信啊.QQ啊之类的通讯录备份,那就等于把自己的通讯录免费送给腾讯他们了....还是自己手动的好一些,但是小白用户或者经常丢手机的卖就卖吧,总比联系人都丢了要好~~~ 默 ...