00:00
由本小节开始,我们继续讲解一下关于面向对象当中继承的问题,在上一小节呢,我们已经为大家介绍了一下继承的实践,对不对?在Python当中我们的继承还可以进行一下分类,那分成什么呢?单继承与多继承好,单继承与多继承好,点击OK啊,创建文文本文件就可以了,来单继承与多继承,那什么是单继承,什么又是多继承呢?从概念上来讲,诶还是比较简单的,所谓的单继承就是指什么呢?一个类只能继承一个父类的方式啊,这种方式我们叫它单继承,然后呢,什么叫多继承呢?好,所谓的多继承就是一个类可以一个类,它写错了啊,一个类可以继承多个负类的方式,这叫做单多继承。那单继承和多继承到底有什么不一样?
01:00
呢,实际上单进程和多继程啊,在开发过程当中我们经常使用到,但是呢,不同的语言对单进程与多进程的知识是不太一样的啊,一般情况下绝大多数都推荐大家使用单继承,但是呢,多继承也是很多语言它所支持一种格式,那单继承我们可以怎样来理解呢?简单的说,我们单继承可以从生物角度来理解一下啊,比如说我们可以从生物角度来理解一下,那怎么样单继承的,比如说我们现在有一个人类对不对,那人类是由哺乳动物继是不是继承哺乳动物类的是不是,所以我们可以写上它继承的是我们的哺乳类动物啊,哺乳类动物,那哺乳类动物。它继承自什么呢?是不是动物,那我们的动物继承自什么呢?哎,继承自生物对不对?继承自生物,然后我们的生物它继承自什么?有机物无机物等等等等等,依次往下类推啊,就可以说人是猴子变的猴,呃,人是什么?猿类变的是不是?猿是猴子变的,猴子是哺是动物变的呀,依次往上追,那大家都知道哈,我们所有地球上生物的祖先无非就是些细菌呗,是不是?再往上追,那就成蛋白质了是不是?所以这种从生物说,从生物角度上来理解,单机种还是比较简单的,人它不可能既继承一个人,呃继承一个哺乳动物又继承一个什么呀,又继承一个,这个叫做呃,叫做鸟类,对不对?那这样的话人不就成了鸟人了,岂有此理啊,是不是?所以呃,在现实逻辑上讲不通啊,这种方式叫做单继成,你会发现这一个类只有一个指定的负类,那什么叫做多继承呢?诶,多继承啊,叫多继承,多继承这块的话,就是从社会角度来讲是比较好理解啊。
02:45
多继承,这个在社会角度来理解还是比较容易的,来社会啊,社会角度来理解还是比较容易的,比如说我现在干什么事儿呢?我现在啊是一个我对不对,我干什么事儿呢?我现在什么都不会。
03:02
什么都不会,都不会,但是呢,我可以拜师对不对,于是乎我有很多很多的师傅,比如说有一个舞蹈的师傅,舞蹈老师他可以教我舞蹈,对不对。教我舞,教舞蹈,然后呢,我还有一个什么老师呢?我还有一个体育老师是不是,那他可以教我什么呀,运动对不对,我还有一个什么呢?我还有一个这个,嗯,比如说我还有这个爸爸,爸爸教我抽烟,是不是抽烟,然后呢,还有一个妈妈,是不是妈妈教我什么呢?打扫卫生啊等等等等等,开始我什么都不会,但是我可以跟他们所有的人一起来学习,对不对,那最后我是不是会什么,我是不是学到的东西都会了,我会舞蹈啊,会舞蹈,我会运动是不是写错了啊运动我会抽烟啊,我会打扫卫生是不是,那这样的话,你可以从社会的角度上来理解这个多基层给大家画个图来理解一下吧,行不行?画图来说更加清晰,打开我们的开始菜单,找到我们的画图板,也就是我们的计算机当中的附件啊,我找找啊,到这附件。
04:15
找到附件当中的画图功能,好,打开我们的画图功能。好,那在这里边我们把刚刚这个小小的这个继承的分类给大家用图的方式说一下行不行,那咱刚开始写的是一个单继承对不对,最下面呢,这块有一个人类啊,这块有一个人类。我们说了这人类吧,它也是寄生子哺乳动物类特征是不是,所以它向上继承了我们另外一个类别啊,叫做哺乳动物。哺乳动物是不是没有人是下蛋的写错了,不是这个哺乳啊,哺乳动物啊,哺乳动物,那我们的哺乳动物它是继承自什么呀?它是继承自动物啊,它就叫做继承自动物。
05:01
来继承自动物对不对,然后动物呢,它在继承自生物。他在继承自生物啊。它为继承生物,这里边写上生物,然后以此类推啊,我就不话太多了,大家看啊,这是我给大家画个箭头表示继承关系啊,人类继承自哺乳动物,哺乳动物继承自动物,动物继承自生物,以此类推。你会发现在这个过程当中,我们所形成的这个什么呀,这个图形是一条直线的,是不是,所以叫单基成啊,当然它之所以叫单基成,是因为它只有一个负类啊,那这就是单继承的一个效果,最终实现的效果就是一个像一个链条一样啊,直接上去了,那多继承呢,则不为其人,多继承则是什么呢?则是这种情况,给大家画图来分析啊,我们刚刚说了啊,这是最下面有一个什么啊,有一个我是不是或者有一个人啊,有一个人,有一个我也行,有一个我,那我可以继承的东西非常多,我可以跟我的舞蹈老师学舞蹈,对不对,这里边有个舞蹈老师啊,哎,我可以从他这儿继承过来什么呀,学舞蹈的功能。
06:14
对呀,我可以从我老师那学习舞蹈嘛,是不是,然后呢,哎,接着来看啊,我还有什么呢,我还有这个体育老师,体育老师教我什么跳高跳远玩铅球啊是不是,所以呢,我可以在体育老师这啊,体育老师这里边儿干什么事呢?诶,我们来学习运动是不是,所以你也可以这种体育老师,一些功能体育老师不教你开始也不会呀,然后呢,我们还有爸爸妈妈教我们做其他事情,比如说妈妈教我们打扫卫生,对不对,妈妈教我们打扫卫生啊。妈妈教我们打扫卫生,那你看在这种关系下啊,我们就它它为多继承,之所以叫多继承,原因是因为我这个类它是不是具有什么呀,多个负类呀,所以这就是多集成的关系啊。哎,多继承。
07:01
好,它是因为具有多个负类啊,具有多个负类,当然很多学民就会有疑问了,说单继承和多继承到底哪个好啊,是不是?实际上哈,我们更推荐大家使用单继承,推荐使用单继承,尽量避免使用多继承啊,避免使用,但不是说不能使用多,基层有专门使用多集成的适合他的一个出场机会啊,但是现实生活中我们还是控,特别是开发过程的啊,提倡大家使用单机层很多说为什么呀,多继承多好啊,一次性把多个东西都塞到一起,是不是那显得工作多强大,说是这么说,在实际工作过程当中,你会发现单继承它由于只继承了一个父类,那么他的什么呀,整个这个继承关系是非常明了的,对不对,而且的父类之间是没有那些乱七八糟的关系的,而多继承就不一样,多继承由一个类可以继承多个类,好像看起来功能非常容易扩大,但是什么呀?它会产生一种很麻烦。
08:02
它的逻辑在当中,特别是我们的继承非常多的时候,为什么呢?很简单啊,你看我继承人的功能没问题吧,是因为我是个人嘛,对不对?但是你看如果你把鸟的功能也放到我身上,我这变成鸟人了,这东西不是不现实中不存在,所以会产生一些逻辑上的问题。另外的话,当你多继承非常多的时候呢,也会非常的混乱,特别是比如说我继承我妈妈的功能是不是,然后呢,我继承我妈妈打扫卫生的功能,然后呢,我姥姥又交给我妈妈的一个功能,我妈妈,我从我妈妈那又继承过来,我又跟我姥姥学了一遍,我从姥爷那学了一个东西,姥姥教给妈妈,妈妈我又从妈妈那也学了一遍,那这样的话,你看似啊我的功能强大了,但实际的最后效果就是某一个功能甚至被你重复学了N遍,某一次操作甚至让你出现N次操作都是可能会出现的多集成的bug啊,当然里边最常见的叫做菱形技术bug,我们一会就给大家讲解好了。而且啊,而且多继承它使用非常的受限,所以大家千万注意尽量使用单继承,但是多继承我会告诉大家什么时候适合使用啊,不要不是说不能用啊,是可以用的啊好了,那既然大大家现在已经差不多了解了我们的单基层与多基层一个什么呀,一个特征对不对?那下面我们就用代码来教大家如何实现一个单基层,如何实现一个多基层,以及看一下它的bug,好吧,好了,那我们先给大家写一个单继承的两案例啊,来写一个单继承的案例,单继承的案例呢,其实我们之前写的都是啊,包括上节课讲的什么复复合子集成是不是都是占集成啊,那这块就需要一个类,是不是需要一个复类,然后呢,里边什么都不需要写啊,然后呢,还需要一个子类啊,子类,然后呢,子类继承父类,这就实现了一个单继承的效果,来我们用代码实现这个单继承案例S文件啊。
09:57
叫它sing sing single啊,OK,表示单个的意思啊来,当然继承叫in hurt,我们就不写那个单词了,好吧,好,单继承,那在这里边我们写一下啊,单继承案例,单继承案例,然后呢,首先呢,我再来给大家写一个什么呢?关于父亲儿子和爷爷的关系行不行,有一个爷爷类写错了爷爷类啊,写错了有一个爷爷类。
10:26
写错了,有一个爷爷类,然后呢,我们还有一个爸爸类是不是,然后我们还一个儿子类啊好,然后在这里边书实现一下这个单机床行不行,首先先写爷爷类啊,爷爷类咱叫他class grandfather行不行?G啊fat grandfather OK,然后在这里边我们给爷爷添加一个功能,添加一个什么功能呢?比如说添加一个这个,呃,是添加一个一些属性和一些方法吧,行不行?属性咱加一个,方法咱也加一个啊。来属性。好,比如说也有什么呢?爷爷有这个肤色,SKN肤色啊,等于黄种人是不是啊,那你能生出黑的也不容易,是不是来黄色人种啊,黄色黄黄黄种人吧,黄种人或者叫皮肤就是黄色怎么样?然后呢,接下来再来一个方法,爷爷会干什么事呢?爷爷会说话呀,DF,我们加一个C的功能,OK,在这里边啊,Print写上一句话。
11:25
爷爷叫做说话中,说话中好没有问题吧,然后呢,在这里边我们再加一个。好,爸爸的累行不行,爸爸的累,然后呢,在这里边class就叫father了,Fat father。然后呢,咱也给他加一个属性,加一个方法行不行,属性啊属性写错了,属性和方法属性咱给他加一个什么东西呢?咱给再加一个眼睛行不行。水汪汪的小眼睛啊,水汪汪的小眼睛,没问题吧?
12:03
好,然后呢,方法再加一个DF,咱加一个什么呢?咱加一个走路啊,Walk考上括号,然后在里边print是不是走走停停中啊。走走停停中散步是不是啊,不是这个停停啊,走走停停。停停。周好,然后呢,再写一个我的类啊,就是我们儿子类行不行,儿子类好,那这个时候大家看啊,Class so丧啊,我在萨里边什么都不加,也就是说这个儿子类里边就是一个空类对不对?所以呢,当我们在这里边实例画一个儿子对象啊,实例画儿子对象这个点倒没什么难度,是不是直接是什么呢?我们的儿子等于son,调用一下这个类的方法就可以了,调一下这个类啊就可以了,然后这个时候我们就得到了一个对象了,Print print框,我们的儿子这个对象。
13:02
好,右键运行一遍。我们可以发现这个对象刚创建出来的时候呢,是是不是儿子类对象没问题,那但是这个儿子类对象里边没什么功能的啊,没什么功能的,比如说在调用一些功能,调用方法吧,方法或者属性或者属性,比如说我们看一下儿子有肤色吗。儿子对象的SK。右键运行一遍啊。报报错,是不是告诉你儿子对象根本就没这个属性对不对,嗯。好,来接着看,那我们看一下儿子,他有眼睛吗?或者有什么样的眼睛吗?来,再次打印,套上括号啊,在里边。然后呢,写上儿子眼睛点Eve有吗?答案也是没有的,也是没有,因为儿子现在是单独存在的一个类,对不对?然后呢,接着看那方法呀,比如说我们儿子会干什么事呢?会说话吗?来。
14:03
儿子对象点CYC套上框来,右键运行一遍。你会发现,哎呀,说话也不能说,那儿子会走路吗?来,我们再来看一下儿子对象啊,他能否进行一个walk走路。右键再嘴行,依然报错啊,依然报错,原因很简单嘛,你在二次类里边是空的,啥也没有,写了个pass对不对,占了一个位置而已,没有任何成属性和方法,那么这样的话,你调用的时候肯定也不存在呀,那怎么样才能让他存在呢?那我们都知道儿子的就要从爸爸那继承了爸爸的功能是不是就可以了?于是乎看好了,我在它的负类当中写上father类,Father类,然后右键运行一遍啊,不会有什么错误的。好,写上father类之后,我们再看一下,如果儿子类继承了father类的话,那按照我们之前讲,他可以把father类中非私有的传属性方法是不是都拿过来啊,所以他就有眼睛和什么呀,走路功能,我们看一下是不是呢,眼睛打开右键运行一下。
15:03
你看眼睛是不是出来了,水汪汪的小眼睛,走路功能它是否会了呢?来,我们看一下,走走天中是不是也会走路了,但是它依然没有任何的肤色,你会发现肤色依然报错,因为他什么呀,他只继承了父亲的特征,而没有继承爷爷的,那怎么办呢?诶,按照单继承来说,我们一个类只能继承一个父类,刚刚儿子类继承了父亲的类是不是?那我这次只需要使用父亲继承爷爷类就可以了啊,这然啊,我用grandfather继承爷爷类,那么这个时候你会发现哦,原来儿子继承了他爹的两个成员,然后他爹继承他爷爷的两个成员,以此类推,儿子实际上继承了什么呀?爷爷和爸爸的所有成员其实一共就四个,这次你再来看一下我们这两个属性和两个方法都可以什么呀,使用了看见了吗。这就是我们的单继承实验效果,注意啊,是单继承的实验效果,而且我也写的是什么呀,生物学上了,一般情况下你都要继承你爸爸的特征啊,对不对。
16:05
好,那这就是一个单继承案例,看懂了吗?啊,也就是说单继承也是可以让儿子继承,这个是列继承过程当中呢,所有类的一些功能的,也就是说在这个单继承过程当中啊,人类其实具有哺乳动物的功能,也有动物的功能,也有生物的功能,因为它们是一层一层的进化而来的,在我们这里说一层一层的继承而来的是不是?所以你说人类是生物对不对,对呀,人类是动物对不对?对呀,人类是哺如动物对不对,也对呀,所以你会发现人类实际上在单机程当中也继承了这个继承过程当中所有类的一些功能,因为他们层层传递嘛,那多继承呢,它就是另外一条道了。来,我们来看一下多继承,来一在这里边先给大家写一下文件啊,那多继承是怎么实现的呢?来看一下多继承案例啊。多继承案例,多继承案例好,那在这里边呢,我们多继承案例可能有多个父类啊,有父类一,有父类二,有负类三。
17:06
等等等等等,可以有很多很多的负类啊,它不限个数的嘛。好。然后呢,在这里边加一个冒号啊,冒号好pass。然后呢,PASS3个负类了吧,对不对。Pass,然后子类它在继承的时候啊,子类在继承的时候,你可以写上多个父类。负类,当然大家说那多负类怎么写,很简单,用逗号分开就可以了,负类一,负类二,逗号负类三,以此类推,这个时候我们就实现了多基层的效果,好了,那我们来看一下啊。多继承的负类行不行啊,不不不,多继承的一个实验开散文件multiple啊,Multiple啊就是多的意思,好不好写一下多几手。这让我想起了一件事啊,什么事呢?那个周星驰曾经演过一个电影,叫什么来着,叫那个就是那个拿菜刀,那个叫什么名了,我想不起来了,叫。
18:07
呃,叫叫叫啥来着,忘了叫啥名了哈,呃,就是007那个叫叫叫叫叫叫国产007,还记不记得那里边有一个特别牛逼的武器,叫要你命3000是不是有什么汽油啊,毒药啊,镰刀啊,砍刀啊,是不是最后绑在一起,是不是这就是要你命3000啊,这个就有点多继成的效果,好了,当然我们就不先讲那个啊,我们的多集成就按照我们刚刚给大家画这个图来介绍吧,行不行?我们刚刚画这个图里边有多个类,是不是有老师,有音乐老师类啊,音乐老师音乐老师类对不对?还有什么呢?还有这个体育啊,体育老师类。老师类,还有这个爸爸类和妈妈类对不对,爸爸和妈妈也是我们的老师嘛,爸爸妈妈来类好类好,在这里边注意啊,我们是从这个社会功能的角度来介绍的啊,首先呢,我们先写一个音乐老师类class,干什么事呢?叫做music teacher啊music teacher。
19:06
DA,好吧,音乐老师类,音乐老师有什么功能,有什么属性呢?我们可以介绍一下,比如说加一个属性吧。属性啊,我们可以写一个干什么事呢,写一个这个C,这个宝贝C啊,就是呃,音乐老师什么属性加什么,加一个言,加一个这个功能性的属性啊,比如说嗯。咱从音乐老师那继承啥,那继承一个,哎,别加属性加方法吧,这个加属性确实不太合适啊,加一个方法行不行,属性咱就给给他留空了,因为你从音乐老师那继承属性怪怪的啊来方法啊,你可以就继承,不过你可以继承他的什么呀,衣着或者品位对不对,我们写上衣着吧,你想学妮老师穿衣服啊,叫做呃,衣着close c。撇一把close啊,等于叫晚礼服行不行?晚礼服咱可以学老师穿衣服呀,晚礼服。
20:00
好,然后呢,加一个方法,那音乐老师自然是唱歌方法了,Sing啊sing套上框。Friend。我们写上啊,门前大桥下路过一群鸭,快来。来快来呢,快来快来数一数二4678好,然后呢,接下来啊,那我们再加一个新的类行不行,这个加一该体育老师类啊class体育体育sport sport吧。Port teacher t,因为体育老师会的就多了,是不是来加方法吧,我就不加属性了,行不行?体育老师方法啊,会干什么事呢?会跑步DEF增加一个run的功能啊,UN啊,这是跑步功能print上括号。跑步,哎,不不写错了啊。跑步功能OK,然后呢,再加啊DF体育老师还会干啥来着,经常体育老师生病,语文老师过来,是不是体育老师再加什么功能呢?再加一个跑步跳高跳远jump吧,行不行?加一个跳跳高的一个功能或者跳远的功能,Plant是不是you jump I jump是不是u jumpmp啊。
21:22
MP逗号I group,好,来接着看再加什么呢?爸爸和妈妈的行不行?Class,呃,叫FA样啊father类,那爸爸会干什么事呢?来,我们加一个方法行不行?加一个方法,比如说爸爸虽然不叫好啊,抽烟类是不是?呃,Smoke SK啊,Smoking。好,Print写上啊。叫叫做什么呢?抽烟中啊,抽烟中写错了,叫抽烟中,不过大家不要学抽烟啊。来,再接下来再来一个妈妈类行不行?Class mother mother mother mother类,Mother类里边来D我们写一个方法,你干什么事呢?打扫卫生的方法叫它可乐行不行?来DFC里液压跑上框,我们可以写上打扫房间啊。
22:16
打扫房间。打扫房间好,然后呢,我们就写完了这四个类,这四个类里边大家会发现啊,基本上它都有什么呀,它都有一些功能,很多说不加属性嘛,不是不加,而是不适合加,因为多继承,你加属性,你从你体育老师那继承了什么呀,性别从你音乐老师那继承了这个什么颜色肤色是不是?嗯,这不觉得怪怪的吗?是不是这玩意不适合生物方面来做啊,因生物方面的话有点有点怪尴尬的是不是。有点绿绿的感觉,好了,我们看一下,这里面还有一个我的类叭,如说class这块有个类叫做me,就是我的类,当然我什么都不会,刚开始对不对,所以呢,会有很多老师来教我,好了,这是我的嘞,剩下的四个类啊,我们也给他标注一下吧,这个是一个妈妈嘞,是不是妈妈嘞?
23:10
上面这个是一个爸爸类,爸爸类,然后再上面是这是体育老师类,体育老师类,然后呢,这是我们的音乐老师类啊音乐老师类,然后呢,大家会发现啊,上面这些类之间是没有什么互没有什么关系的,就是体育老师和音乐老师有关系吗?没什么关系,爸爸和体育老师有关系没有啊,妈爸和体育老师有关系吗?也没有关系,而不像单继承,单继承我们这个继承关系中你会发现啊,你和爸爸有关系,爸爸和也有关系是不是?所以我们按照这个关系串起来,就实现了单继承而多继承,因为他们类之间不存在逻辑关系,所以你不可能使用单层的方式来做,比如说哎呀,我继承妈妈类,妈妈类继承爸爸类,爸爸类继承体育老师类,体育老师就是音育老师类,这样在逻辑上是不同的明白,所以呢,我们为了让逻辑通顺,并且让功能可以实现,我们要使用多继成来进行操作啊,多继成就是你要从这上面这些人多继成啊,学到很多很多的功能,对不对?那怎么做呢?很简单。
24:10
在我的后面加括号就可以了,然后呢,写上你所需要继承的父类,用逗号分割,比如说我想继承妈妈类,从妈妈那类学者的Mo mother类,从妈妈类学点东西,然后呢,我们还可以想想从爸爸那学点东西,Father类对不对?我想从音乐老师学点东西啊,Music teacher。然后我还想从体育老师学点port提成好,那这个时候多提成就写完了,很多时候有顺序关系吗?没有,你随便谁前谁后都一样啊,但是在特殊情况会有一些,呃,不一样,我们一会再讲好,那在这里边我们继承时间了之后,实际化对象行不行,实际化对象好,我们的对象呢,就叫做什么I啊,就是我等于调用me这个类。然后呢,这个时候请注意,由于我的类已经继承了上面所有的类,所以实际上在这里边我具有上面所有继承过来类容的功能和属性的,那在这里边我们写上这个啊,调用成员行不行?比如说我想看一下我的这个品位啊,咱就是i.close是不是i.CTHI我的衣服CTH来大家看一下是不是继承了音乐老师的晚礼服对不对?那我想唱歌没关系,i.C叫s sing套上括号来右键运行边程线程序啊,看是不是门前大家下路过去啊,是不是大山歌,我想跳,我想跳高跳远是不是i.jump从体育老师那学的gump套上框,大家来看一下体育老师的功能,我也学过来对不对?体育老师还有一个跑的功能嘛,I点。
25:46
2.r朝上框右键运行一遍。好,你看一下跑步功能是不是有了,还有从爸爸那学的抽烟功能,对不对?爱点smoke。OK in OK in,好,套上括号表扬了,右键月线一遍你会以发现,诶,抽烟也可以对不对?还从妈妈那学打扫卫生了i.clear野呀啊,See yeah呀,好,看一下,打扫卫生你学会了吗?
26:12
来在里边大家来看一下,哎,美甲上右键预习一遍。你会发现打扫卫生的功能我是不是也学会了,这就是多继层的使用操作,看懂了吗?诶,是单继层的,多继层实际上看起来是一样的,但实际上它的业务逻辑上是完全不一样的。单继承的业务逻单继承的逻辑非常明确,每一个类之间得互相有关系,我最后得能串成这么一条直线,是不是和一个令,然后呢,多几成的不是它要求负类之间有没有关系跟我无所谓啊,是不是,但是我都可以往我身上塞。那么在大多数人,特别是出数者来看,说哎呀,多基层多方便啊是不是?那这样的话,我岂不是有什么类都可以往里边一塞,哎,就解决问题了吗?有什么功能往里塞就解决问题了吗?问题就出现在你这种想法当中,因为当一个类中塞入了过多的东西的时候,反而会出现什么呀问题或者叫做bug。
27:07
一逻辑上不统顺,第二在使用上会有很大很大的弊端啊。那有什么弊端呢?导致我们尽量推荐大家使用单继承而非多继承呢?这就涉及到的多继承的一个bug叫做菱形继承bug继承啊,给大家看一下多继承中存在而单继承中不存在的菱形bug问题。好,在这里边打开我们的文档啊,给大家介绍一下多继承的问题所在啊,多解缩了叫做多继承的问题所在,也就是我们的菱形bug。写错了,不是这个菱形啊,菱形菱形啊bug,或者叫做钻石,钻石菱形继承啊,菱形继承写错了,菱形继承或者钻石继承中的问题,好,为了实现菱形继承和钻石继承,大家都先搞明白一件事情,啥叫菱形集成,啥叫钻石集成啊,是不是?好在我们刚刚画的多集成中非常简单,因为这个多集成实际上只有两层关系,一个是负累,一个是子类,对不对?但是如果你的父类还有父类呢?
28:18
来给大家看一下领取继承bug到底什么,什么图形好不好,给大家画个图来介绍介绍一下,把这张图先保存一下啊,我们写下这个继承in her h here啊好保存一下这个图我们先留这,然后呢,然后呢,我们新建一个图给大家看一下菱形继承是什么样的,所谓的菱形继承就表示我最终类的继承关系形成了一个菱形,很多是为什么叫钻石继承呢?是不是长得像钻石嘛,是不是有尖有棱角的吗?然后在这里边会出现这种情况,最顶层有一个类,我们可以叫它A类,行不行,或者叫它类A都行啊,叫A类,然后呢。最左边有一个类,左边这个类呢,我们可以叫它B类,行不行叫它B类啊,右边还有一个类叫做C类。
29:08
啊,这个叫做B类,这个叫做C类啊,叫做CC类,然后呢,最下面有一个子类叫做D类。啊,这下面有一个类,这个叫做D类这样的四个类,或者说是更多的都可以啊,但是要形成这种结构啊,D类这种类中啊,继承中就存在我们所谓的菱形继承的bug很多,说这个bug到底是啥意思啊,好,先不管bug啥意思,我一会让你看,我们先看一下这个零生经行关系,你是否搞明白了。这个也说啊,也说只要实现这个效果,其实就是B类继成A类,C类继成A类,D类继成B类和C类,是不是就可以了?好,用了这个例子之后,我们下面教大家问题的所在,以及实现行不行?好了,在这里边为了实现菱形继承问题,或者叫做钻石继承问题,我们得新建一个文件,文件啊,文件在里边我们写上一个菱形,菱形英文单词怎么说啊,好,呃,我们写上一个这个,呃,我还真不会写菱形啊。
30:11
写写写拼音丢音,写拼音丢人的话,咱写一个呃bug行不行,写上一个bug啊bug或者叫做继承bug吧。Inher,啊in hurt bug行不行?这是第一个文件哦,因为得写多个文件好了。我们刚刚说了有四个类嘛,是不是菱形继承。菱形继承写错了,叫菱形。继承我们这里面需要四个类,哪四个类呢?ABCD4个类行不行,A类啊A类。然后呢,B类。然后呢,C类。然后C类,然后D类,好,当然我在这里边会用一些不切实际的一些力,行不行,我们把A类比作是人类啊呸呸呸,比作是动物类怎么行,就是一种动物啊,生活叫生物类啊,B类我们把它比作人类,然后呢,C类我们把它比作鸟类。
31:14
鸟类,那么在这里边大家看啊,人类继生动物类很正常嘛,对不对,鸟类继生动物类也正常,好D类啊,这个是不存在的,什么类呢?鸟人类啊,也就是说类似于雷震子这样的鸟人类,那鸟人类是不是既有鸟的功能,得会飞呀,又得有人的功能,会说话,会有智慧工具啊,对不对?所以这就是我们刚刚写的这个。这个ABCD4个类,我们给它取了一个现实中的名字,行不行?这样好理解一点,好了,有了这四个类之后呢,我们来实例化这四个类,不不不,我们来定义这四个类,好吧,来,下面来看一下动物类。好,动物类这里边我们class叫animal行不行,Animal类啊,就叫做animal,然后呢,Pass一下。然后呢,我们还有需要一个人类对不对,好人类,我们先给它起个名字,人类叫什么呢?诶,咱叫他human啊,就是人类的英文单词嘛,Human。
32:08
好,Pass一下,先不用写方法和生源啊,然后再一个鸟类啊鸟类,再写一个鸟类,鸟类呢,最简单鸟类,鸟类就是bird呗,Class bird啊bird好,Pass一下,然后再写一个鸟人类啊鸟人类这个简单,其实缺一点像蜘蛛侠,什么蜘蛛和人放在一起不就是蜘蛛侠吗?好,我们鸟类和人类放一起就是雷震子,这里边class。蜘蛛侠叫spman,是不是我们叫它birdman行不行?BRD啊birdman好,那这样一来的话,我们叫四个类就存在了,但这四个类之间目前来说还没什么关系,对不对?所以呢,我们要在这四个类写一下继承关系嘛,这个打字我刚刚说了,我们的人类是要继承鸟类的。啊不不,什么鸟类哈,人类要继承动物类的,我们的鸟类呢,也要继承动物类,所以在这里边动物类其实就是A类。
33:05
A类,然后呢,我们的人类就相当于B类啊,就相当于B类,然后呢,鸟类就相当于C类,你看ABC的关系,是不是B和C都记成A类,也就是符合我们这个图形中的关系,B和C都记成A类对不对?好,反过去看一下我们最后一个D类,D类要记成B类和C类,所以在D类这里边我们要写上。B类和C类的继继承啊,那写B类的话,B类叫多了括号啊,B类叫叫什么来着啊,叫人类啊hum man还要继承鸟类是bad,好,那这样的话我们的什么呀,鸟人类也继承了人类和鸟类,是不是从业务逻辑上不会有任何语法问题,因为我们写的对呀,好,但是看好了很多说这个东,你说这个技承有bug bug在哪呢?下面我们给这个所有方法里加一个功能,什么功能呢?说话的功能,这个大家都知道,无论是什么样的动物啊,鸟类啊是不是都会叫啊,是不是我们可以在里边弄一个发音的一个功能行不行?好添加一个叫做发音的写错误常数,叫做发声吧,发声啊的方法,那动物类的发声方法里边我们定义一个方法叫C行不行?
34:14
好,然后这个方法里边我们写两句话啊。叫做动物类,准备开始发音。然后呢,再写一个print,动物类,发音结束,看好了,别写动物类,写animal类吧,行不行A啊,写汉字也没关系啊,反正不影响,然后呢,第二个我们就写上AI写错了,A ni animal。类叫做什么呀?发音结束看懂了吗?结束,也就是说一张一闭呗,是不是一张ABB啊,动物类这个方法,那么动物有这个功能,人有没有这个功能,有啊,因为动物有声带,人是不是有声带啊,所以人继承动物类的时候,自然有它发生的方法,但是人说的方法是不是比它要更高级一点,对不对,也就说比我们这个什么呀,这个动物类的发声要更高级一点,那这个时候呢,我们在定义人类的发声,发发声或者叫发音都行啊,发音的方法。
35:17
好,叫什么呢?我们要继承它,还要比它高,所以其实就是在这里边重新定义一个思维方法,覆盖动物的方法,那这个时候我们还希望是不是调继承它的功能啊,是不是,也就是说你需要在这里边把它再调用一次,那在这里边我们这样写,看好了,Print写上。Hu hum humanly叫做准备开始发音啊,然后呢,Print套上括号,我们写上啊,叫做human human类发音结束,好,那在这里边大家都知道我们人类的功能是不是要继承动物,还要比动物更高啊,所以在这里边看好了,我加一层叫做调用啊,父类中的发音功能啊,这有点像什么刘禅做皮鞋和刘备做草鞋,你继承你爸的做草鞋功能,这个工艺是一样的,材料不一样而已,对不对?我们这也是一样啊,我们在这里边人类发生的时候要调用动物发音的一个功能,那在这里边怎么调用动物呢?请问animal。
36:23
Ni ni写错了,Ni。animal.c讨论框,这是把动物的发育方法调过来了,但是调过来的时候注意看好了,因为人家方法里有S,你这个调用的时候得传个参数对不对?很多说传什么呀,那自然是人类借助动物方法发音了,那就把人类自己这个selff缩到这里边就可以了,很那这个问题吗?没有任何问题啊,你看动物类发音的时候是不是需要个主体对象,那我写SF,这个SF在这里边你可能传一个动物进去,对不对?那我人类教语的时候把人自己创进去,那是不是就是人自在这使用动物的发音功能好没问题,有问题吗?没问题啊,好,来接着看,那鸟类也有一个发音的功能,你鸟也会叫啊,是不是?来咱也写一个发音的方法。
37:11
发写错了啊叫发音的方法,好在这里边我们调用一下第定义一下这个发音方法,还叫C啊,还叫C,然后呢,在这里边鸟类说话自然和什么呀,动物说话一样啊,和人类说话一样,继承子动物还要比动物高是不是,所以我们这边写上一个bird类啊类,准备开始发音。然后呢,也有个结束啊,一张一闭好多说为什么这么写,一会你就知道了,好吧,一张一闭的让你看的更清楚,一对一对的啊,然后point类啊,发音结束,那当然鸟类在发音的时候,是不是也要从继承字父类的发音功能啊,是不是,所以在这里边我们要调用啊,看好了就要调用副类的发音功能,那这块还是动物类呗,Animal点什么呀?C,这个时候我们把谁呢?把S传进去,那这个S是不是鸟鸟追小本人了是不是?好了,接下来前两个都写完了,看最后鸟人类,这个鸟人类的它也加一个发音的方法。
38:12
发音的方法保证什么呢?他说的话你能听懂,人也能听得懂,是不是这有点像那个蜘蛛侠一样,是不是跟蜘蛛可以聊天,虽然电视里面演,但是漫画里演的很多很多,还有还有什么蚁人是不是可以跟蚂蚁说话,也可以跟人说话,诶这个效果也就很像,所以在里边咱也加一个说话的话。好,为了保证呢,我这里边儿说的话,人家能听懂,你那样能听懂,所以在这里边干什么事呢?看好了,我在这里边自己要发音,毫无疑问也就说在这里边啊。我们要写上叫做brotherman啊,写错了。Birdman。们,他的泪。那。准备开始发音,然后呢,Bird类bird类它的发音结束啊,这个都是成对开始成对结束的啊简三。
39:07
发音结束,但是为了让他的什么呀,为了让这个发音功能人也听懂,哪也听懂,所以我们要在这里边盖成这。调用人类的什么呀发音。发音,还要调用鸟类的发音。因为你要既让人听懂,也让鸟惊懂嘛,是不是我说了只要大家看过蚁人都知道,那蚁人是不是可以跟蚂蚁沟通啊,是不是他当然也可以跟人沟通啊,所以这其实要学习什么蚂蚁的一些呃,功能哈,好第二人类的方法简单,人类human human ma human,他的发音叫C嘛,对不对,然后呢,你把咱自己S传进去,第二鸟类bird类套上框啊,点CC弹框,把S也放进去,好看起来是不是非常的完美,是不是确实啊,写起来也很流畅,好很多时候问题有问题吗?没有问题啊,有没有问题用的时候才知道,我们在这里看好了,实例化。
40:08
一个鸟人的对象啊,好在里边啊,Birdman啊,叫BM等于b birdman。好,当然这个类里边只有一个方法,所以调用方法也很简单,就调用方法呗,来调用说话方法。来bm.ay当然他说的话既要保证人能听得懂,也要保证是不是这个鸟也听懂啊,也就说它里边肯定会调用鸟和人的发音功能好,有没有问题呢?程序右键运行程序,好,大家发现出来了一大堆信息啊,首先在里边看啊,首先最外层一定是鸟人类在说话,看见没有,它是对称的啊,最外层一定鸟人类的说话对不对?那鸟人说话有没有借助人类的功能呢?大家会发现里边确实借助了人类的功能啊,写错了,在这呢啊,人类是不是在这儿确实借助了人类的发音,所以。
41:03
他说的话能听懂,那这里面有没有借助鸟的发音呢?鸟开始发音,鸟发音结束,是不是也也用了,也说鸟也听懂,好像看似一切很完美。是从右逻,从这个什么呀,现实逻辑中好像没有问题,但是从开发过程当中,你会发现这里边儿出现了一个很尴尬的东西,就是。动物类发音用了两次,很多,这两次就两次,但你别忘了,你只说了一次话。让人和鸟都听得懂,但是你却调用了两次发音方法,就意味着你发了两次音,这就是业务逻辑的问题所在。很多说这个好像也没有问题啊,问题大了,你说一遍和说两遍能一样吗?不一样,如果说我们刚刚这里边定义的最开始啊,动物类定的不是一个说话方法,而在现实中是一个计时方法,怎么办呢?那你再看你这个运行结果啊,这是一个计时方法,你会发现运行结果里边计了两次时,看见了吗?所以会导致程序出现偏差,看见bug所在了吗?也就是最开始这个,如果它不是一个简单说法,而是一个计时的话,你会发现这个计时方毕竟有两次,肯定验落就有问题吧,肯定程序会出bug是不是,所以问题就在这,也就是说无论我们使用什么样的计承来实现,必须保证这个方法只出现一次,才可以出现两次计算计时两次嘛,是不是,所以我们就是这这个就称之为菱形bug啊。
42:30
零星寄生装B。这叫做菱形G写错了啊,菱形写错了。菱形。继承中的bug所在。所在啊,它的所在就在于某个方法,某个方法在继承写错了啊,某个方法在继承中被多次调用,但实际上多次调用,实际上只需要调用一次就可以,你看你之前画的那幅图。
43:05
我们A类、B类、C类之所以形成了菱形关系啊,是不是D类一定要用啊,D类找B找CC和B是不是同时找A啊,所以相当于找了两次A,这就是菱形继承bug所在啊,如果该方法为G,如果该方法是不是叫做具有啊唯一或者是什么呀,或者是计时的特性。嗯,计时呢,或者计时特性啊,计时类似的特性会调用,会出现程序会出现错误啊,特性则。无法使用。这就是我们菱形集成的bug所在,所以无论是多继承也好,还是写的成继承也好,好像都没什么难度吧,是不是bug也给大家展示出来了?那如何解决菱形进程当中bug的问题呢?好了,我们本小节到此结束,感谢大家收看,我们下一小节再见。
我来说两句