我們知道面向對象三大特性封裝会通、繼承口予、多態(tài),然而OC我認為嚴格意義上來說不算是純面向對象語言涕侈,例如它沒有構造器的概念沪停,它的多態(tài)性質有一些奇怪的地方。Swift終于回歸正常裳涛,我以前做過java開發(fā)木张,對比著思考,Swift語言面向對象性質和java非常類似端三,下面我會舉個例子來對比OC和Swift多態(tài)的性質舷礼。
在對比OC和Swift多態(tài)性質之前,我先強調一下滿足多態(tài)的條件技肩。
多態(tài)三要素:
1. 類繼承
2. 方法override
3. 父類對象指向子類
- 先看Swift實例
class A: NSObject {
override init() {
super.init()
bbb()
aaa() // 多態(tài)
}
func aaa() {
print("classA ------> aaa()")
}
private func bbb() {
print("classA ------> private bbb()")
}
}
// B繼承于
class B: A {
override init() {
super.init()
}
override func aaa() {
super.aaa()
print("classB ------> aaa()")
super.aaa()
}
private func bbb() {
print("classB ------> private bbb()")
}
}
這段實例代碼再簡單不過了且轨,假如我們在外面調用B()
,你覺得輸出結果是什么呢虚婿?
classA ------> private bbb()
classA ------> aaa()
classB ------> aaa()
classA ------> aaa()
看看你設想的輸出結果是否和答案一致旋奢,如果不一致的話,說明面向對象還領悟的不到位然痊,需要繼續(xù)領悟至朗。
- 那么接下來看一下奇葩的OC會是什么樣的結果
@interface A : NSObject
- (void)aaa;
@end
@implementation A
- (instancetype)init
{
if (self = [super init]) {
[self bbb]; // 重點思考:會調用哪?剧浸?锹引?
[self aaa];
}
return self;
}
// public method
- (void)aaa
{
NSLog(@"classA ------> aaa()");
}
// privateMethod
- (void)bbb
{
NSLog(@"classA ------> private bbb()");
}
@end
// ================================================
@interface B : A
@end
@implementation B
- (instancetype)init
{
if (self = [super init]) {
}
return self;
}
// override
- (void)aaa
{
[super aaa];
NSLog(@"classB ------> aaa()");
[super aaa];
}
// privateMethod
- (void)bbb
{
NSLog(@"classB ------> private bbb()");
}
@end
這里我說明一下,注釋雖然標識了privateMethod唆香,OC嚴格來說是沒有公有方法和私有方法這么一說的嫌变,全看.h是否暴露。這段OC代碼和上面的Swift代碼類似躬它,那么在外面執(zhí)行[[B alloc] init]
會有什么輸出結果呢?
classB ------> private bbb()
classA ------> aaa()
classB ------> aaa()
classA ------> aaa()
請仔細思考一下腾啥,在A
的init
方法中,[self bbb]
為什么沒有調用自己,而是調用到子類中倘待,然而類A中的bbb這個方法并沒有被子類override疮跑,正常的面向對象,這里是不滿足多態(tài)的性質的凸舵,類之間是有隔離的祖娘,應該調自己才是,然而OC會調到子類去了啊奄,這是因為OC是保存方法列表的渐苏,會在B類包過其父類所有方法列表去尋找往哪調,所以就調到B里面的bbb方法中去了增热,設想一下整以,假如我們繼承一個第三方沒開源的一個類,在我們自己的類中寫了一個私有方法峻仇,這個時候恰好這個私有方法和父類重名公黑,是不是有可能發(fā)生一些低概率的悲劇事件,也正是因此摄咆,我會覺得OC的面向對象有點奇怪