21、你新创建的初始化方法中必须有一个是该类的指定初始化方法。应该选择哪一个呢?
指定初始化方法通常是参数最多或者在设置对象时执行最多工作的初始化方法。对于不需要带参数的初始化方法的类,指定初始化方法是 init 。
22、在类的初始化过程中,对于初始化器的调用有什么要求?
在设计类的初始化器时,所有其他类初始化器必须最终调用该类(而非超类)的 指定初始化器 。
- 指定初始化器 是能完全初始化类实例的初始化器,通常是参数最多或在设置对象时执行最多工作的初始化器。
例如, TeeShirt 类中, initWithShirtSize: 调用了指定初始化器 initWithShirtSize:color: 。
- 并且,类的 指定初始化器 必须调用其超类的 指定初始化器 ,这是唯一调用超类指定初始化器的初始化器。
23、别忘了修复初始化方法。
该表述提醒开发者对初始化方法进行检查和修正,确保其能正确初始化对象,避免初始化失败或出现内存管理问题。
在初始化方法里,要做好非 dealloc 处理的清理工作,释放对象并返回 nil 以表明初始化失败,同时要保证在失败点调用类的 dealloc 方法是安全的。
24、假设你有一个抽象类Dog,以及它的子类AmericanDog、JapaneseDog和ItalianDog。你需要编写一小段代码来记录狗的叫声。以下代码有什么问题(这是一个设计问题,而非语法问题):Dog *myDog = … if ( [myDog isMemberOfClass: [AmericanDog class]] ) { NSLog(“woof woof”); } else if ( [myDog isMemberOfClass: [JapaneseDog class]] ) { NSLog(“wan wan”); } else if ( [myDog isMemberOfClass: [ItalianDog class]] ) { NSLog(“bau bau”); } 如何改进这个设计?如果添加一个FrenchDog子类,旧版本和新版本的代码需要如何修改?
原代码的问题在于违反了开闭原则,当添加新的狗子类时,需要修改原有的判断逻辑。
改进设计方案:
- 在
Dog类中定义一个抽象方法,如-bark。 - 在每个子类中实现该方法,返回对应狗的叫声。
对比分析:
- 旧版本代码 :添加
FrenchDog子类时,需新增一个else if分支判断。 - 新版本代码 :只需在
FrenchDog子类中实现-bark方法,调用时直接使用[myDog bark]即可。

最低0.47元/天 解锁文章

被折叠的 条评论
为什么被折叠?



