问题的发现:今日笔者在复习Category的相关知识时,突然发现了一个有趣的小问题,即当一个类的两个(或者更多)分类有同名的方法时,当该方法被调用时,究竟会调用哪一个分类里的方法呢?
如下图所示:


两个分类都有eat方法,然后创建Person对象,并调用该方法,再运行一下,打印结果会是怎样的呢?
好吧,不卖关子了,打印的结果如下:

说明调用了MS分类里的eat方法。
那为什么会调用MS分类的eat方法而不调动MT分类里的方法呢?
难道是两个类的摆放顺序不同导致的?还是随机调用这些分类里的同名方法?
可是我在尝试改变分类的摆放顺序和多次运行后发现,结果还是没变,那到底是怎么回事呢?
在查阅了相关资料后我才弄明白这个问题,原来这与类在编译时的顺序有关。
如下图所示:

在Compile Sources这一栏里,我们可以看到程序编译时要编译的文件,可以看到MS分类是排在MT分类的后面,因此它的eat方法会覆盖MT分类的eat方法,因此调用的eat方法是MS分类的,这下真相重要大白了!不信的话,我们来验证一下。
在交换了MT和MS在Compile Sources这一栏的位置后,我们再运行程序,最后的打印结果如下:

此时调用的是MT分类里的eat方法!
虽然这个问题很小,或者说是一个冷门的知识点,但是在我求根溯源的过程中我还是收获了不一样的快乐和成就感~
网友评论