注:
定义类时类名应该加上两个大些字母前缀,以下代码类名并没有规范,比如例子中Car类可以更改为CDCar
面向过程和面向对象
面向过程是祈使句,面向对象是主谓(宾)结构。
面向过程注重数据的存储和操作,面向对象注重用程序模拟生活逻辑。
面向过程数据和操作数据的过程是分离的,没有逻辑上的必然联系;面向对象中数据和操作数据的方法是逻辑上的整体,称之为对象。
面向对象的基本概念
对象:现实世界中的对象是我们认识世界的基本单元,世界就是由这些基本单元组成的。一切皆为对象;每个对象都是独一无二的;对象都有属性和行为;对象都属于某个类。
类:类是对一组具有共同属性和行为的对象的抽象,它是对象的蓝图和模板。
消息:对象与对象之间存在着一定的联系,这种联系通过消息的传递来实现。程序中的一切操作都通过向对象发送消息来实现,对象接收到消息后,调用有关对象的行为来完成相应的操作。
面向对象的三大支柱
封装是把一个事物包装起来,使外界不了解它的内部的具体情况。在面向对象的程序设计中,封装就是把相关的数据和代码结合成一个有机的整体,形成数据和操作代码的封装体,对外只提供一个可以控制的接口,内部大部分的实现细节对外隐蔽,达到对数据访问权的合理控制。封装使程序中个部分之间的相互联系达到最小,提高了程序的安全性,简化了程序代码的编写工作。
继承是从已有的类创建新类的过程,提供继承信息的称为父类,得到继承信息的称为子类,子类和父类之间是IS-A关系,继承使得类与类之间形成一个层次结构。
多态是不同结构的对象可以以各自不同的方式响应同一个消息,或者说同一个消息可以根据发送消息的对象的不同而采用多种不同的操作行为,这是面向对象最精髓的部分。
类的定义和实现
数据抽象和行为抽象
从问题描述中勾出所有的名词和动词,名词会称为类或者类中的属性,动词会成为类中的方法。
数据抽象:找名词(对象的属性)
行为抽象:找动词(对象的方法)
类的.h文件
#import <Foundation/Foundation.h>
@interface Student : NSObject {
@private char _name[10];
@private int _age;
}
- (instancetype) initWithName:(const char *) name age:(int) age;
- (void) study:(const char *) courseName;
- (void) watchJapaneseAV;
@end
类的.m文件
#import "Student.h"
@implementation Student
- (instancetype) initWithName:(const char *) name age:(int) age {
if(self = [super init]) {
strcpy(_name, name);
_age = age;
}
return self;
}
- (void) study:(const char *) courseName {
printf("%s正在学习%s\n", _name, courseName);
}
- (void) watchJapaneseAV {
if(_age >= 18) {
printf("%s正在观看岛国爱情动作片\n", _name);
}
else {
printf("%s未满18岁不允许观看岛国爱情动作片\n", _name);
}
}
@end
构造方法
见上面的代码。
类的实例化
#import <Foundation/Foundation.h>
#import "Student.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
Student *stu = [[Student alloc] initWithName:"王小二" age:16];
[stu study:"Objective-C程序设计"];
[stu watchJapaneseAV];
}
return 0;
}
创建对象的语法
见上面的代码。
访问对象属性及访问修饰符
- @private:私有,对外界来说是不可见的。
- @protected:受保护,对子类相当于公开;对其他类相当于私有。
- @public:公开,对外界来说是可见的。
给对象发消息
Objective-C中给对象发消息使用中缀符(infix notation)语法,方法的名称及其参数都是合在一起的,如上面的代码所示。
示例
写一个汽车类并为其拟定一个速度属性,汽车的速度只能通过踩油门和踩刹车两个行为来改变。
- h
#import <Foundation/Foundation.h>
@interface Car : NSObject{
@private NSInteger _speed;
}
-(instancetype)initWithSpeed:(NSInteger) speed;
- (NSInteger) speedUp: (NSInteger) num;
- (NSInteger) speedDown:(NSInteger) num;
@end
- m
#import "Car.h"
@implementation Car
-(instancetype)initWithSpeed:(NSInteger)speed{
if (self = [super init]){
_speed = speed;
}
return self;
}
-(NSInteger)speedUp:(NSInteger)num{
_speed += num;
return _speed;
}
-(NSInteger)speedDown:(NSInteger)num{
_speed -= num;
return _speed;
}
@end
- main
#import <Foundation/Foundation.h>
#import "Car.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
Car *car = [[Car alloc] initWithSpeed: 30];
NSLog(@"起始速度%d",30);
//加速
NSLog(@"加速后%ld",(long)[car speedUp:20]);
//减速
NSLog(@"减速后%ld",(long)[car speedDown:40]);
}
return 0;
}