iOS 继承
一、继承
不恰当的使用继承导致的最大的一个特征就是高耦合。
是否使用继承需要考虑三个点:
- 父类只是给子类提供服务,并不涉及子类的业务逻辑
- 层级关系明显,功能划分清晰,父类和子类各做各的。
- 父类的所有变化,都需要在子类中体现,也就是说此时耦合已经成为需求
万不得已不要用继承,优先考虑组合等方式。
如果只是共享接口,我们可以使用协议;
@protocol ptc <NSObject>
- (void)do;
@end @interface A : NSObject<ptc>
@end @implementation A
- (void)do
{
}
@end @interface B : NSObject<ptc>
@end
@implementation B
- (void)do
{
}
@end
如果希望共用一个方法的部分实现,但希望根据需要执行不同的其他行为,我们可以使用代理或者 AOP;
@protocol ptc <NSObject>
- (void)do;
@end @interface A : NSObject
@property (nonatomic, weak) id<ptc>delegate;
@end @implementation A
- (void)func
{
...
[self.delegate do];
...
}
@end @interface B : NSObject <ptc>
@end @implementation B
- (void)do
{
}
@end
如果是添加方法,我们可以优先使用类别;
如果是为了使用一个类的很多方法,我们可以使用组合来实现。
@interface A : NSObject
- (void)methodA;
@end @interface B : NSObject
-(void)methodB;
@end // 定义 C 以及其需要的 methodA,methodB
@interface C : NSObject
{
A * __a;
B * __b;
}
- (id)initWithA:(A *)a b:(B *)b;
- (void)methodA;
- (void)methodB;
@end @implementation ClassC
- (id)initWithA:(A *)a b:(B *)b
{
__a = [[A alloc] initWithA:a]; // [A copy];
__b = [[B alloc] initWithB:b]; // [B copy];
}
- (void)methodA
{
[__a methodA];
}
- (void)methodB
{
[__b methodB];
}
@end
如果只是出于代码复用的目的而不区分类别和场景,就采用继承是不恰当的。当你发现你的继承超过 2 层的时候,你就要好好考虑是否这个继承的方案了,第三层继承正是滥用的开端。
二、多态
使用场景:
- 父类有部分public的方法是不需要,也不允许子类覆重
- 父类有一些特别的方法是必须要子类去覆重的,在父类的方法其实是个空方法
- 父类有一些方法是可选覆重的,一旦覆重,则以子类为准
- 父类有一些方法即便被覆重,父类原方法还是要执行的
通常带来的问题:
- 容易使得一个对象引入原本不属于它的业务逻辑
- 调用时机或忘记调用
解决方案:
- 面向接口编程(Interface Oriented Programming, IOP)
在决定是否采用多态时,要有一个清晰的角色概念,做好角色细分,不要角色混乱。
三、封装
将相关的一堆函数和一堆对象放在一起,只留给外部程序员操作方式,而不暴露具体执行细节。
带来的问题:
- 制约了并行程度
- 数据部分就是数据部分,执行部分就是执行部分,不同类的东西放在一起是不合适的
四、内容来源
casatwy & 跳出面向对象思想(一) 继承
跳出面向对象思想(二) 多态
跳出面向对象思想(三) 封装
iOS架构师之路:慎用继承
iOS 继承的更多相关文章
- ios 继承UITableViewController,更改tableview样式
// 继承UITableViewController,更改tableview样式 - (instancetype)initWithStyle:(UITableViewStyle)style { ret ...
- ios 继承关系图
- IOS入门之Swift语言(一)
经过不断的努力,小哥也买了台苹果设备,终于可以开始我的IOS之旅了,说来确实令人苦恼,为了学习IOS我这着贫农阶级,省了几个月的零花钱,外加向亲朋好友求救,最终痛下心扉,卖了台MAC pro128G版 ...
- iOS项目开发日常之创建文件(协议、类、分类、扩展)
iOS项目开发过程中,是以不断创建文件的形式进行着的. 创建得比较频繁的文件类型是: 这两个类型中创建的文件有:子类.分类.扩展.协议四种文件,如下: 这四类文件是频繁创建的,我们来看一下各自分 ...
- 字符串流sstream[part1/基本知识]
C++中的输入输出分为三种:基于控制台的I/O,即istream.ostream.iostream:基于文件的I/O,即ifstream.ofstream.fstream:基于字符串的I/O,即ist ...
- C++ stringstream介绍,使用方法与例子
From: http://www.usidcbbs.com/read-htm-tid-1898.html C++引入了ostringstream.istringstream.stringstream这 ...
- stringstream
C++引入了ostringstream.istringstream.stringstream这三个类,要使用他们创建对象就必须包含sstream.h头文件. istringstream类用于执行C++ ...
- C++ 系列:iostream 的用途与局限
转载自http://www.cnblogs.com/Solstice/archive/2011/07/17/2108715.html 本文主要考虑 x86 Linux 平台,不考虑跨平台的可移植性,也 ...
- 30分钟学会Objective-C
注: 本文首发于我的个人博客:https://evilpan.com/2019/04/05/objc-basics/ 请原谅我的标题党.但是如果你有其他语言的学习经验,要学习Objective-C的语 ...
随机推荐
- ASP.NET CORE 启动过程及源码解读
在这个特殊的春节,大家想必都在家出不了们,远看已经到了回城里上班的日子,但是因为一只蝙蝠的原因导致我们无法回到工作岗位,大家可能有的在家远程办公,有些在家躺着看书,有的是在家打游戏:在这个特殊无聊的日 ...
- 零基础JavaScript编码(二)
任务目的 在上一任务基础上继续JavaScript的体验 学习JavaScript中的if判断语法,for循环语法 学习JavaScript中的数组对象 学习如何读取.处理数据,并动态创建.修改DOM ...
- 前端开发--nginx篇
安装和启动 Mac上搭建nginx教程 通过Homebrew 安装nginx brew install nginx 配置 添加配置文件在 /usr/local/etc/nginx/servers 目录 ...
- Promise,Generator,Await/Async
上节中忘记讲:Iterator接口和Generator函数的关系了,Symbol.iterator方法的最简单的实现就是通过Generator函数: let myIterable = { [Symbo ...
- python学习-练习题1巩固(随机数)
1.生成随机数 random.random()生成一个0-1之前的随机数
- AX2012/D365 SSRS报表开发
大家好,好久没有做SSRS报表了,近期刚好有做2张,就整理起来供初学者参考. AX中SSRS报表开发的框架,父类非常多,这里跟大家简单分享2种比较常用的场景供大家使用. 1.简单的过滤字段,无特殊过滤 ...
- JsonFormat 日期少了8个小时?还我
JsonFormat 后日期少了8个小时什么鬼? 前言 今天测试的时候发现时间对不上,比数据库里的时间少了8个小时?测试小姐姐一顿狂轰乱炸,一点都不温柔. 什么鬼?哪里出了问题?数据库显示的是下面
- 建议8:恰当选用if和switch
相对来说下面几种情况更适合switch结构 枚举表达式的值.这种枚举是可以期望的,平行逻辑关系的 表达式的值具有离散性,不具有线性的非连续的区间值 表达式的值是固定的,不是动态变化的 表达式的值是有限 ...
- C# 时间戳(TimeStamp)与时间(DateTime)的互相转换
什么是时间戳:时间戳是指格林威治时间1970年01月01日00时00分00秒(北京时间1970年01月01日08时00分00秒)起至现在的总秒数. 时间戳在线转换网址:https://tool.lu/ ...
- Linux服务器(Centos)上安装jexus
哈子是Jexus Jexus是一款Linux平台上的高性能WEB服务器和负载均衡网关,Jexus Web Service,简称JWS,以支持ASP.NET.ASP.NET CORE.PHP为特色, 同 ...