关于Objective-C和C++中的继承及其区别

 

最近在看一个开源项目的代码(iOS上的抽屉式视图MMDrawerController,Github地址:https://github.com/mutualmobile/MMDrawerController),当看到其中一个地方的时候,发现自己的基础知识真是太渣了。。。

问题是这样的:类B有两个实例方法method1和method2,method1中调用了method2;类D继承自类A,并实现了自己的method1和method2,然后在D的method1中通过super调用父类A的method1。那么,最后执行的是父类A的method2还是子类B的method2呢?

 

经过一番验证,自然是得到了答案。然后我有想到了下面几个问题:

  1.  同样学得半吊子的C++里,这种情况是调用method1还是method2来着?
  2.  Objective-C中,如果method2是私有方法,又会如何?
  3.  对于2中的情况,C++中是什么样的?

 

话不多说,针对原先的问题,代码如下:

关于Objective-C和C++中的继承及其区别
@interface B : NSObject

- (void)method1;
- (void)method2;

@end

@implementation B - (void)method1 { [self method2]; } - (void)method2 { NSLog(@"Base method2."); } @end
关于Objective-C和C++中的继承及其区别
关于Objective-C和C++中的继承及其区别
@interface D : B

@end


@implementation D

- (void)method1
{
    [super method1];
}

- (void)method2
{
    NSLog(@"Derived method2.");
}

@end
关于Objective-C和C++中的继承及其区别

 在main函数中执行:

D *d = [[D alloc] init];
[d method1];

结果为:Derived method2. 可以看出,调用的是子类D的method2方法。

 

 

那么,在C++中又会如何呢?同样用代码来说话:

关于Objective-C和C++中的继承及其区别
class B {
public:
    void method1();
    void method2();
};

class D : public B {
public:
    void method1();
    void method2();
};

void B::method1()
{
    method2();
}

void B::method2()
{
    cout << "B" << endl;
}

void D::method1()
{
    B::method1();
}

void D::method2()
{
    cout << "D" << endl;
}

int main(int argc, const char * argv[])
{
    D *d = new D();
    d->method1();
    
    delete d;
    return 0;
}
关于Objective-C和C++中的继承及其区别

执行结果为:B ,调用的是父类的方法。

可是如果要像Objective-C中一样调用子类D的方法,该怎么做呢?虽然我的C++是半吊子,还是想起了虚函数。在父类的method2声明前加上virtual关键字,然后执行的结果就会变成 D 了。

 

(这时会发现,我这个例子和通常C++参考书里讲虚函数的例子有所不同,那些例子类似于:

B *d = new D();
d->method2();

即用父类指针指向子类对象,然后调用一个虚函数。

两个例子虽然长得不同,不过本质还是一样的嘛,都是根据对象的实际类型调用相应的方法。)

 

 

好了,进入下一个问题:如果method2是私有方法会如何?

修改代码,注释掉method2得声明:

@interface B : NSObject

- (void)method1;
//- (void)method2;

@end

运行后会发现,调用依然的是子类的方法。虽然method2是私有的,还是被子类覆盖掉了。。。这点需要注意,尤其是在子类化苹果的框架和第三方类库的时候。

然后看C++,如果加了virtual的话,同样会被覆盖,不过private方法谁闲着没事加个virtual呢。

 

 

综上,Objective-C中的方法相当于自动加了virtual(如果要避开这种多态的特性需要进行合理的设计);子类化时需要避免可能对父类私有方法的覆盖。

 

关于Objective-C和C++中的继承及其区别

上一篇:Python爬虫从入门到放弃(十七)之 Scrapy框架中Download Middleware用法


下一篇:从上帝视角看OS进程调度