定义
- 面向对象编程(OOP,Object Oriented Programming),以类(Class)和对象(Object)作为组织代码的基本单元(广义定义),并将封装,抽象,继承,多态四个特性作为代码设计和实现的基石(严格定义);
- 面向对象编程语言(OOPL,Object Oriented Programming Language),支持类或对象的语法机制,能够方便实现面向对象编程的四大特性;
- 面向对象分析(OOA,需求分析),面向对象设计(OOD,系统设计),面向对象编程(OOP)是面向对象编程的三个重要阶段。OOA和OOD产出类的详细设计供OOP使用。
- 统一建模语言(UML,Unified Model Language),用于开发过程中绘制类图、例图、顺序图、活动图、状态图、组件图等。
主要特性
面向对象编程的四大特性为:封装,抽象,继承,多态
- 封装(Escapsulation),信息隐藏或数据访问保护
- 实现封装的语法机制为访问权限控制
- 访问权限控制降低了灵活性,但显著提高了可控性
- 访问权限控制提高了易用性
/**
Wallet.h
**/
@interface Wallet : NSObject
@property (nonatomic, strong, readonly) NSString *id; // 只读,不允许修改
@property (nonatomic, assign, readonly) NSTimeInterval *createTime; // 只读,不允许修改
@property (nonatomic, assign, readonly) NSInteger balance; // 只读,允许间接修改
@property (nonatomic, assign, readonly) NSTimeInterval *lastModifiedTime; // 只读,允许间接修改
// 存入金额
- (void)increaseBalance:(NSInteger)increased;
// 取出金额
- (NSInteger)decreaseBalance:(NSInteger)decreased;
@end
```objective-c
/**
Wallet.m
**/
@interface Wallet ()
@property (nonatomic, strong, readwrite) NSString *id;
@property (nonatomic, assign, readwrite) NSTimeInterval *createTime;
@property (nonatomic, assign, readwrite) NSInteger balance;
@property (nonatomic, assign, readwrite) NSTimeInterval *lastModifiedTime;
@end
@implementation
- (instancetype)init
{
if (self = [super init])
{
self.id = [[IDGenerator getInstance] generate];
self.createTime = [[NSDate date] timeIntervalSince1970];
self.balance = 0;
self.lastModifiedTime = [[NSDate date] timeIntervalSince1970];
}
return self;
}
- (void)increaseBalance:(NSInteger)increased
{
self.balance += increased;
self.lastModifiedTime = [[NSDate date] timeIntervalSince1970];
}
- (NSInteger)decreaseBalance:(NSInteger)decreased
{
self.balance -= decreased;
self.lastModifiedTime = [[NSDate date] timeIntervalSince1970];
}
@end
- 抽象(Abstract)隐藏方法的实现,告知调用方类提供的功能;
- 借助编程语言提供的接口类和抽象类实现;
- 关注功能点而非设计思路,过滤非必要信息
- 方法的定义和实现都需要有抽象思维
@protocol RACSubscriber <NSObject>
@required
- (void)sendNext:(nullable id)value;
- (void)sendError:(nullable NSError *)error;
- (void)sendCompleted;
- (void)didSubscribeWithDisposable:(RACCompoundDisposable *)disposable;
@end
- 继承(Inheritance),用来表示类之间的IS-A关系
- 存在两种模式:单继承和多继承
- 有利于代码复用
- 多态(Polymorphism),在代码运行过程中,子类可以替换父类,调用子类的方法实现
- 多态实现的方法1:继承
- 多态实现的方法2:接口类
- 多态实现的方法3:Duck-Typing(鸭子类型)
// 基于继承的多态
// Parent Class - Animal
@interface Animal : NSObject
- (void)run;
@end
@implementation Animal
- (void)run
{
NSLog(@"I can run.");
}
@end
// Child Class - Cat
@interface Cat : Animal
@end
@implementation Cat
- (void)run
{
NSLog(@"I can run with my four legs.");
}
@end
// Child Class - Duck
@interface Duck : Animal
@end
@implementation Duck
- (void)run
{
NSLog(@"I can run with my two legs.");
}
@end
//
@interface TestViewController : UIViewController
@end
@implementation TestViewController
- (void)viewDidLoad
{
[super viewDidLoad];
NSMutableArray<Animal *> *animals = @[].mutableCopy;
Duck *duck = [[Duck alloc] init];
[animals addObject:duck];
Cat *cat = [[Cat alloc] init];
[animals addObject:cat];
for (Animal *animal in animals)
{
[animal run];
}
}
@end
// 基于接口类的多态
@protocol AnimalWithLegs <NSObject>
@required
- (void)run;
@end
// Class - Cat
@interface Cat : NSObject <AnimalWithLegs>
@end
@implementation Cat
- (void)run
{
NSLog(@"I can run with my four legs.");
}
@end
// Class - Duck
@interface Duck : NSObject <AnimalWithLegs>
@end
@implementation Duck
- (void)run
{
NSLog(@"I can run with my two legs.");
}
@end
//
@interface TestViewController : UIViewController
@end
@implementation TestViewController
- (void)viewDidLoad
{
[super viewDidLoad];
NSMutableArray<id<AnimalWithLegs>> *animals = @[].mutableCopy;
Duck *duck = [[Duck alloc] init];
[animals addObject:duck];
Cat *cat = [[Cat alloc] init];
[animals addObject:cat];
for (id<AnimalWithLegs> animal in animals)
{
[animal run];
}
}
@end
// 基于🦆类型的多态
class Logger:
def record(self):
print(“I write a log into file.”)
class DB:
def record(self):
print(“I insert data into db. ”)
def test(recorder):
recorder.record()
def demo():
logger = Logger()
db = DB()
test(logger)
test(db)
面向过程 🆚 面向对象
- 面向过程以过程(函数,Operator)作为组织代码的基本单元,主要特点是数据与方法分离,通过顺序拼接一组方法操作数据完成一项功能。
- 面向对象比面向过程更适合大规模程序的开发;
- 面向对象编程输出的代码更加易用,易扩展,易维护;
- 面向对象编程语言更加高级,人性,智能;
导致面向对象退化的编程方式
- 滥用getter && setter破坏封装特性
- 滥用全局变量和全局方法
- 全局变量:单例对象,静态成员变量,常量
- 全局方法:静态方法
- 定义数据和方法分离的类,如基于贫血模型的开发模式;
抽象类 🆚 接口
-
基于抽象类可以实现:面向对象继承特性,模版设计模式,JAVA中的抽象类:
- 抽象类只能继承,不能实例化
- 抽象类可以定义属性和方法,无实现代码的方法叫抽象方法
- 子类必须实现抽象类中的所有抽象方法
- 相较普通的类,抽象类有利于提高代码可读性,鲁棒性,简洁性
-
基于接口可以实现:面向对象抽象特性,面向对象多态特性,基于接口而非实现的设计原则,JAVA中的接口:
- 接口不能包含属性
- 接口只能声明方法,不能实现方法
- 类必须实现接口中的所有方法
- 接口侧重于解耦,提高代码灵活性,可扩展性
-
抽象类是特殊的类,符合IS-A关系,接口表示一种HAS_A关系,JAVA中的接口和Objective-C中的协议类似;