面向对象的三大特性

  1、封装

  2、继承

  3、多态

一、封装

将类内部的属性保护起来,在外部不能直接访问,那么如果需要访问怎么办呢?

OC提供了set方法来对成员变量进行访问

set方法

1、作用:提供一个方法给外界设置age属性的值

2、命名规范

  方法名必须是set开头

  set后面跟上成员变量的名称,成员变量首字母必须大写

  返回值一定是void

  一定要接收一个参数,并且和成员变量类型一致

   形参名不能和成员变量名一样

声明

- (void)setAge:(int)newAge;//声明

实现

 - (void)setAge:(int)newAge//set方法实现
{
if(newAge <= )//如果小于0岁就赋值为1
{
newAge = ;
}
age = newAge;//设置年龄
}

使用

  Student *p = [Student new];//新建对象
[p setAge:];//设置属性
[p study];//调用方法

get方法

1、作用:返回对象内部的成员变量

2、命名规范:

肯定有返回值,返回类型和成员变量一致

方法名和成员变量名一样

不需要接收参数

声明

- (int)age;//

实现

 - (int)age//
{
return age;
}

使用

  NSLog(@"%d岁的学生在学习!",[p age]);

成员变量的使用

命名规范:

  成员变量都以下划线 _ 开头

  可以跟get方法的名称区分开

  可以跟其他局部变量区分开,一看到下划线开头的变量,肯定是成员变量

 @interface Student : NSObject
{
//@public
//成员变量
//让成员变量和get方法区分开,成员变量都要加_
int _no;
int _age;
Sex _sex;
} @end

练习1

 #import <Foundation/Foundation.h>

 //成绩类
/*
C成绩(读写)
OC成绩(读写)
平均分(只读)
总分(只读)
*/
//类的声明
@interface Score : NSObject
{
int _cScore;//c成绩
int _ocScore;//oc成绩 int _totalScore;//总分
int _averageScore;//平均分
} //方法声明
//set
- (void)setCScore:(int)newCScore;
- (void)setOcScore:(int)newOcScore; //get
- (int)cScore;
- (int)ocScore;
- (int)totalScore;
- (int)averageScore; @end //类的实现
@implementation Score
//方法实现
- (void)setCScore:(int)newCScore
{
_cScore = newCScore;
//计算总分和平均分
_totalScore = _cScore + _ocScore;
_averageScore = _totalScore/;
}
- (void)setOcScore:(int)newOcScore
{
_ocScore = newOcScore;
//计算总分和平均分
_totalScore = _cScore + _ocScore;
_averageScore = _totalScore/;
} - (int)cScore
{
return _cScore;
}
- (int)ocScore
{
return _ocScore;
}
- (int)totalScore
{
return _totalScore;
}
- (int)averageScore
{
return _averageScore;
}
@end int main()
{
Score *p = [Score new];//新建对象
[p setCScore:];//set方法
[p setOcScore:];//set方法 NSLog(@"总分:%d",[p totalScore]); NSLog(@"平均分:%d",[p averageScore]); return ;
}

OC弱语法

如果调用不存在的方法,那么在编译和链接时都不会报错,最多有一个警告。只有在运行时才回出错。

unrecognized selector sent to instance 0x0000034034C0

给对象发送的消息不能识别

OC只有在运行过程中才会检测对象有没有实现相应的方法。

类方法

1、以+开头

2、通过类名调用的方法。

3、类方法不能访问成员变量

4、类方法和对象方法可以重名

5、使用场合:当不需要访问成员变量时尽量用类方法

声明

+ (void)printClassName;//

实现

 + (void)printClassName//
{
NSLog(@"class name is Person");
}

使用

 [Person printClassName];//类方法的调用,直接使用类名

工具类

没有成员变量的类,里面的方法全是类方法。

示例

 #import <Foundation/Foundation.h>
/*
工具类
没有成员变量
所有方法全是类方法
*/
//类声明
@interface JiSuanQi : NSObject + (void)printClassName;//类方法 + (int)sumOfSum1:(int)sum1 andSum2:(int)sum2;//类方法 @end
//类的实现
@implementation JiSuanQi
+ (void)printClassName
{
NSLog(@"class name is JiSuanQi"); }
+ (int)sumOfSum1:(int)sum1 andSum2:(int)sum2
{
return sum1 + sum2;
} @end int main()
{ [JiSuanQi printClassName];//类方法的调用,直接使用类名
int res = [JiSuanQi sumOfSum1: andSum2:];
NSLog(@"%d",res);
return ;
}

self关键字

谁调用,self代表谁。

如果用对象调用,就代表对象,如果是类调用,就代表类。

成员变量和局部变量同名

  当成员变量和局部变量同名时,采取就近原则,访问的是局部变量

  用self访问成员变量,区分同名的局部变量

self出现的位置:

  所有的OC方法中(对象方法\类方法),不能出现在函数

作用方式:

  使用 "self->成员变量名" 访问当前方法调用的成员变量

  使用 "[self 方法名];" 来调用方法(对象方法\类方法)

 - (void)setAge:(int)newAge
{
_age = newAge; int _age = ;//局部变量与成员变量同名时,如果需要使用成员变量,则需要使用self关键字
NSLog(@"age is %d",self->_age);//self 是一个指指针,指向调用的对象
}

 小练习

  设计Car类,一个对象方法跟其他车子比较车速,返回速度差,一个类方法比较两辆车的车速,返回速度差

 #import <Foundation/Foundation.h>

 //类的声明
@interface Car : NSObject
{
int _speed;//速度
}
- (void)setSpeed:(int)newSpeed;
- (int)speed;
//对象方法
/*
作用:比较两辆车的速度大小,返回差值
方法名:differenceSpeedWithOtherCar:
参数:(Car *)otherCar
返回值:int
*/
- (int)differenceSpeedWithOtherCar:(Car *)otherCar; //类方法
/*
作用:比较两辆车的速度大小,返回差值
方法名:differenceSpeedWithCar1: :
参数:(Car *)Car1 (Car *)Car2
返回值:int
*/
+ (int)differenceSpeedWithCar1:(Car *)Car1 andCar2:(Car *)Car2;
@end //类的实现
@implementation Car
//对象方法的实现
- (void)setSpeed:(int)newSpeed
{
_speed = newSpeed;
} - (int)speed
{
return _speed;
} //对象方法
- (int)differenceSpeedWithOtherCar:(Car *)otherCar
{
return [self speed] - [otherCar speed];//self指向调用者也就是本对象
} //类方法 + (int)differenceSpeedWithCar1:(Car *)Car1 andCar2:(Car *)Car2;
{
return [Car1 speed] - [Car2 speed];//通过类调用的话,只能传进来两个参数,因为默认成员变量是0,没有任何实际意义。
} @end int main()
{
Car *p1 = [Car new];
[p1 setSpeed:]; Car *p2 = [Car new];
[p2 setSpeed:]; Car *p3 = [Car new];
[p3 setSpeed:]; int res = [p1 differenceSpeedWithOtherCar:p2];//使用对象调用方法
NSLog(@"%d",res); res = [Car differenceSpeedWithCar1:p1 andCar2:p3];//使用类调用方法
NSLog(@"%d",res);
return ;
}

二、继承

子类从父类继承一些公共属性和方法。

不允许子类和父类拥有同名的成员变量。

方法可以和父类的方法同名(重写),调用过程是先找子类的,再找父类的。

继承的使用场合

  1、当两个类拥有相同的属性和方法时,可以将相同的东西抽象到一个类中

  2、当类a中含有类B所需的全部或部分属性和方法时,可以让B继承A

继承与组合区别

  继承:A 是 B;

  组合:A 拥有B;

示例

 #import <Foundation/Foundation.h>

 //Animal类的声明
@interface Animal : NSObject
{
int _age;//年龄
double _weight;//体重
}
//对象方法
- (void)setAge:(int)newAge;
- (int)age; - (void)setWeight:(int)newWeight;
- (double)weight; - (void)run;
@end //Animal类的实现
@implementation Animal
//方法实现
- (void)setAge:(int)newAge
{
_age = newAge;
}
- (int)age
{
return _age;
} - (void)setWeight:(int)newWeight
{
_weight = newWeight;
}
- (double)weight
{
return _weight;
} - (void)run
{
NSLog(@"动物在奔跑!");
} @end //Dog类的声明
@interface Dog : Animal
{
//int _age;//子类不能和父类的成员变量重名
int gouPai;//狗牌
}
//对象方法
- (void)run;//重写父类的方法
@end //Dog类的实现
@implementation Dog
//方法实现
- (void)run
{
NSLog(@"Dog在奔跑!");
} @end //Cat类的声明
@interface Cat : Animal
{ }
//对象方法 @end //Cat类的实现
@implementation Cat
//方法实现 @end int main()
{
Dog *d = [Dog new];
[d setAge:];
[d run];//子类的run会覆盖父类的run方法
NSLog(@"%d",[d age]); return ;
}

super关键字

如果在子类中想访问父类的方法(对象方法和类方法都可以),可以使用关键字super进行调用 ;  

[super walk];//具体是对象方法还是类方法取决于调用时所处于的环境。

使用场景:子类使用父类的方法时想保留父类的一些操作

 //方法实现
- (void)run
{
NSLog(@"Dog在奔跑!"); [super run];//super 关键字,调用父类的方法
}

三、多态

  父类指针指向子类对象:多态

1、没有继承就没有多态

2、父指针指向子类对象

3、优点:函数/方法传入父指针,则在调用时可以传入子类指针和父类指针

4、缺点:父类类型的变量,不能直接调用子类特有的方法

代码示例

 #import <Foundation/Foundation.h>
/*
多态 */ //Animal类的声明
@interface Animal : NSObject
{
// int _age;//年龄
//double _weight;//体重
}
//对象方法 - (void)eat;
@end //Animal类的实现
@implementation Animal
//方法实现
- (void)eat
{
NSLog(@"吃吃吃!");
} @end //Dog类的声明
@interface Dog : Animal
{
//int _age;//子类不能和父类的成员变量重名
//int gouPai;//狗牌
}
//对象方法
- (void)eat;//重写父类的方法
@end //Dog类的实现
@implementation Dog
//方法实现
- (void)eat
{
NSLog(@"Dog在吃吃吃!"); // [super eat];//super 关键字,调用父类的方法
} @end //Cat类的声明
@interface Cat : Animal
{
//int _age;//子类不能和父类的成员变量重名
//int gouPai;//狗牌
}
//对象方法
- (void)eat;//重写父类的方法
- (void)run;
@end //Dog类的实现
@implementation Cat
//方法实现
- (void)eat
{
NSLog(@"Cat在吃吃吃!"); // [super eat];//super 关键字,调用父类的方法
}
- (void)run
{
NSLog(@"Cat在跑!");
}
@end int main()
{
//Dog *d = [Dog new]; //父类指针指向子类对象:多态
Animal *a = [Dog new];
//[a run];//父类指针调用子类的特有方法,会有警告 Dog *d = (Dog *)a;//可以强制转换,调用子类特有的方法
[d eat]; return ;
}

IOS开发学习笔记010-面向对象的三大特性的更多相关文章

  1. iOS开发学习笔记:基础篇

    iOS开发需要一台Mac电脑.Xcode以及iOS SDK.因为苹果设备都具有自己封闭的环境,所以iOS程序的开发必须在Mac设备上完成(当然,黑苹果应该也是可以的,但就需要花很多的精力去折腾基础环境 ...

  2. ios开发学习笔记(1)

    objective-c基础总结 第一二章 1.application:didiFinishLauchingWithOptions:程序启动后立即执行 2.启动界面代码格式:self.window = ...

  3. iOS开发学习笔记

    1 常用的第三方工具 1.1 iPhone Simulator 测试程序需要模拟器iPhone Simulator 1.2 设计界面需要Interface Builder,Interface Buil ...

  4. ios开发学习笔记(这里一定有你想要的东西,全部免费)

    1,Search Bar 怎样去掉背景的颜色(storyboard里只能设置background颜色,可是发现clear Color无法使用). 其实在代码里还是可以设置的,那就是删除背景view [ ...

  5. ios开发学习笔记040-autolayout 第三方框架Masonry

    不管是是界面创建约束还是代码创建约束,苹果官方提供的方式都比较繁琐.所以出现了第三方框架. Masonry 在github地址如下: https://github.com/SnapKit/Masonr ...

  6. IOS开发学习笔记017-第一个IOS应用

    第一个IOS应用程序,就从最简单的开始吧. 1.先了解一下开发环境,Xcode的相关组成 2.还有模拟器 3.运行与停止按钮 4.新建一个工程 5.看看main函数里都有啥 6.现在来添加一个控件 1 ...

  7. IOS开发学习笔记009-OC基本知识

    开始学习OC,时间不等人啊,要抓紧了. OC基本知识 新建一个以.m结尾的文件,这既是oc的程序文件.在oc程序中完全兼容C语言.编译好链接类似. oc包含头文件是使用#import <> ...

  8. (ios开发学习笔记一)ios项目文件结构

    转自:http://www.cnblogs.com/macroxu-1982/archive/2012/07/31/2616389.html 下面是单个窗体项目例子,我们从这个项目开始,说明ios项目 ...

  9. IOS开发学习笔记026-UITableView的使用

    UITableView的简单使用过程 简单介绍 两种样式 UITableViewStylePlain UITableViewStyleGrouped 数据显示需要设置数据源,数据源是符合遵守协议 &l ...

随机推荐

  1. [荐]推荐一个shell学习的网站

    最近再用shell脚本,发现一个脚本学习的网站,非常好用,特此推荐一下. shell学习网站链接:http://c.biancheng.net/cpp/shell/

  2. 【Java/Android性能优5】 Android ImageCache图片缓存,使用简单,支持预取,支持多种缓存算法,支持不同网络类型,扩展性强

    本文转自:http://www.trinea.cn/android/android-imagecache/ 主要介绍一个支持图片自动预取.支持多种缓存算法.支持二级缓存.支持数据保存和恢复的图片缓存的 ...

  3. 将表格table作为execl导出

    有时候的需求是从后台获取数据,然后将数据变成execl,进行导出,下载成execl 解决的方法是 一,比较方便的是 这有个插件 可以直接用 https://www.npmjs.com/package/ ...

  4. [转]Cannot deserialize the current JSON array (e.g. [1,2,3]) into type

    string content =[{"id": 3636, "is_default": true, "name": "Unit&q ...

  5. IOS 监听键盘的通知(NSNotificationCenter)

    通知方法: /** * 当键盘改变了frame(位置和尺寸)的时候调用 */ - (void)keyboardWillChangeFrame:(NSNotification *)note { // 设 ...

  6. Android(java)学习笔记76:Handler用法总结 和 秒表案例

    一.Handler的定义: Handler主要接收子线程发送的数据, 并用此数据配合主线程更新UI,用来跟UI主线程交互用.比如可以用handler发送一个message,然后在handler的线程中 ...

  7. Android(java)学习笔记88:BaseAdapter适配器重写之getView()

    1. BaseAdapter适配器重写 之getView(): (1)View getview(int position, View convertview, ViewGroup parent ) 第 ...

  8. WARNING: The TCP backlog setting of 511.解决

    redis启动警告问题:WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/so ...

  9. 如何更改VirtualBox虚拟电脑内存大小

  10. OO第四单元总结

    单元架构设计 本单元OO作业主要涉及两个过程,即先根据输入的elements数组建立UML存储模型,而后基于这个模型实现一系列查询判断功能.汲取上单元的经验,建模过程中模型数据容器的选择依据要求实现的 ...