00:00
好,刚刚我们说了,呃用了几个视频,我们来说了一下,我们面向对象的一个特征叫做封装,接下来我们来说我们面向对象的下一个特征,还是新创建一个文件来说它,我们零八叫做一个什么呢?叫做一个继承,呃继承这个意思就很明显了,对吧?我们都知道,像我们说我们的这个儿子,哎,可以继承父亲的财产,或者说这个,呃,现在开放了,对吧,女儿也可以,就说孩子可以继承父母的财产,对吧?这么一个继承,你说你父母东西都可以给你,这叫做一个什么呀?叫做一个继承,那在我们的这个诶语言中,在我们这个编程里边,什么是继承呢?那这样我们先不管它啊,我们还是先创建一个诶类,我们先创建一个小的一个小的一个DEMO啊,在这儿我们来干嘛呢?诶我们来定义一个这个类,诶一个类叫什么呢?诶叫做animal啊animal什么意思。
01:00
对,动物啊,Animal是动物的意思啊,来表示这个动物,那这个类中呢,哎,这个类比较简单啊,这个类中需要什么呀?哎需要两个方法,哪两个方法,一个我们叫做一个run,哎,Run跑的方法,还有个叫什么呢?叫做一个哎,Sleep,我们这个睡觉的方法,哎就这么一个东西,我们来看看怎么定义啊,怎么定义在这里我直接来一个这个class class后边跟的是我们的这个类名,类名我们叫做一个animal啊animal后边冒号我是不是可以写内容了,哎,我现在呢,哎没有规定里边有哪些属性,所以在这我先不考虑属性,我直接写这两个方法,两个方法在这儿我们来定义一个,第一个我们叫做一个这个run run方法非常简单,在这儿我直接打印一个,打印一个叫什么呢?诶动物会跑啊,会跑,这是第一个方法,然后第二个方法,我们直接来一个定义一个我们叫做一个,诶sleep,诶sleep在这我们来写什么呢?我们来写一个这个。
02:00
我们叫做一个动物干嘛呢?哎,动物睡觉,诶睡觉就这么两个方法,就这么一个类,非常简单,当然现在你也可以去创建一个它的实力,直接来一个A,等于一个这个按钮,然后在这儿我们直接来一个A,点一个run,我这一执行是不是动物会跑就执行了呀,诶是这样一个效果啊好,那现在我们删掉,把这类留在这里,那好,那现在有这样一个类了,有这样一个类,那现在我要有一个需求了,我要干嘛呢?哎,我现在还想干嘛呢?哎,我还想定义一个类,什么类呢?叫做一个DOGDOG什么意思啊,Dog是一个狗啊狗,那这个类中呢,诶这个类中我们需要什么呢?诶需要三个方法,哎三个方法一个什么呢?Run,还有一个是诶sleep,还有一个什么呢?还有一个我们叫做一个这个bar。哎,Bug狗叫啊,狗叫的方法啊,Bug叫做一个bug,那现在我定义这个狗这个类呢,它非常简单对吧?哎,非常简单,直接定义就完事了,但是这里边我们就会发现一个问题,实际上狗这个类它有两个方法,和animal里边的方法是重复的,也就是说。
03:13
Run和sleep在animal里有,在狗这个里边是不是也有啊,哎,也有run和sleep,那现在我们就面面临到一个什么呀,面临到一个问题,那现在什么问题呢?诶我们什么呀?诶我们现在干嘛呢?诶我们现在有一个类,诶有一个类干嘛呢?诶能够实现我们什么呀?诶我们需要的这个大部分功能,诶但是什么呢?诶但是它不能实现我们这个全部功能,什么意思?我们现在需要一个狗这么一个类啊,狗这么一个类,狗这么一个类里边需要三个方法,一个是RA,一个是sleep,还有一个是B,那你会发现实际上如果你只需要run和sleep的话,现在animal这个类是不是已经完全可以满足我们的需求了?哎,你直接用animal就行了,但是不巧的是,狗这里边还需要一个这个B,而这个方法在animal里边是不是。
04:13
没有的呀,哎,没有的,也就是说现在实际上animal这个类能实现我们大部分功能,Run和sleep都能实现,但是它现在不能实现什么呀,我们的这个全部功能,那怎么办?那怎么办?那我们怎么能解决这问题,怎么怎怎么解决这问题,那就是说诶我们来说一下,那我们如何能让这个类来干嘛呢?来实现我们这个全部的功能呢?诶如何能让这个类来实现我们全部的功能呢?那这里边我们想想我们有什么方式,那第一种方式我们显而见可以想到第一种方式什么样?我们直接干嘛呢?诶修改这个类,哎,修改这个类干嘛呢?在这个类中,诶添加什么呀,我们需要的一个功能什么意思?现在我们需要一个狗狗,需要三个方法,而animal里边只有两个方法,那怎么办?那我可以直接在这儿,我再定义一个什么,定义一个方法,直接定义一个,我们叫做一个这个。
05:14
哎,Bark bark呢,在这我们直接来一个这个print,哎,Print我们来写什么呢?哎,写一个动物,哎动物哎嚎叫,哎动物嚎叫我写这么一个对吧?B这么一个方法,那这样是不就OK了,哎这样就OK了,我直接去添加这个方法,这是我们第一个方式直接修改这个类,在类中添加我们需要的功能,但是这种方式会有什么问题啊,会有什么问题,首先我们说这种方式修改起来干嘛?修改起来会比较麻烦,为什么麻烦?因为我们如果说这个方法比较多,现在我只需要扩展一个,如果我方法比较多的话,我是不是都得添加呀,哎修改起来比较的麻烦,并且它最关键的是,并且会违反我们这个什么呀,OCP这个原则,什么叫NNCP叫做一个开闭原则,什么叫开?我们对扩展开放,对修改是关闭的,而我现在添加这么一个bug方法是不是等于?
06:14
在修改这个animal这个类啊,那我修改这个bug,实际上它只需要用用于我这个狗类这个对象,而对于其他类这个对象,我这个bug实际上是没用的,那我这个修改会不会影响到其他对象呢?那这就不一定了,对吧,所以在这儿我们是不应该去修改的,这样一修改可能会有一些隐患,并且其实改起来也并不方便啊,并不方便,所以这种方式直接修改的方式是我们不推荐的啊,这是我们说的第一种方式,那第二种方式除了直接修改,我们还可以干嘛?第二种方式我们还干嘛?哎,我们直接干嘛呀,哎,我们直接创建一个,哎,新的嘞啊新的嘞,哎,那你现在想了,我需要一个狗,那这个animal有我需要,但是大部分都都不一样,那我干嘛呀,我直接把这东西给它复制一下呗,复制一下我把这类名改成一个什么呀,改成一个叫做DOGDOG,那我们这里边三个方法呗,我都写上,哎,我直接改一。
07:14
对吧,这个是什么呀,这个是狗会跑,这个是一个什么呀,狗睡觉这个是一个什么呀?哎狗叫哎狗叫就汪汪汪呗,对吧,汪汪汪,哎,那这样是不是就OK了,哎这样就OK了,所以第二种我可以直接创建一个什么呀,哎新的类你直接创建就完了啊创建完了诶那这种方式有什么麻烦呢?同样它也是一个问题,那我们说了创建一个新的类也是比较什么呀,比较麻烦啊,比较麻烦,并且需要什么呢?诶需要大量的。诶进行什么呀?诶复制粘贴,诶复制粘贴会出现什么呢?诶会出现我们这个大量的重复性代码,什么意思?你会发现其实刚才我这个创建dog的时候,我是直接把哎很多东西都复制过来的,复制过来我把这东西改吧改吧改吧改吧,加了一个bug是不是这个类就出来了,那但是其实这两个方法它是不是都是一样的,哎都是一样的,那是不是这儿就等于出现重复的代码了,哎那你现在两个方案还好,那我如果有十个方法呢?如果有我有1000个方法呢?也就是说这1000个方法你出现重复出现了两次,那这样我们的代码维护起来是不是比较麻烦呀,较麻烦呀,如果你要改的话,你是不是每一个都得改呀?哎,所以这一块就比较的麻烦,所以这种方式也不好啊,这种方式也不好,那怎么办,那怎么办,那这里边我们就要说到我们的第三种方式。
08:47
第三种方式是什么?第三种方式就是我们说什么呀?哎,我们直接从什么呢?诶从我们这个animal,诶这个类中干嘛呢?诶来继承它的什么呀?哎,它的这个哎属性和方法,那什么叫继承,那第三种就是我们说的一个叫做继承,那继承是什么啊,这个应该是这个它啊这个它那什么叫继承,那注意了,继承也是我们这个面象对象的三大特性之一,诶面向对象的三大特性之一,那继承有什么作用,那继承就像什么呀,我们这个子女从父母那儿继承财产一样,那什么呢?哎,通过继承我们可以什么呢?哎,我们可以使一个类,诶获取到什么呀?哎,其他类中的这个属性和方法啊,其他类中的属性和方法,那什么意思,我们直接来演示,那现在比如说我。
09:47
我们还是要创建一个dog类,而在这个dog类里边,我现在需要animal这里边的什么,这个run和sleep,那这个时候这个dog类我要怎么去创建?诶,那注意了,我们直接来一个class,来一个这个dog,诶那之前我们说了,我这还写一个pass,那这个是不是就是一个单纯的dog类啊,哎,就是一个单纯道类,那之前我们去创建这个类的时候,我们来定义类的时候,我们说了这个语法在类名后边跟一个括号,是不是可以指定一个负类啊,哎,指定一个负类,那在这里边我们在这儿的时候,我就可以干嘛呢?哎,我可以在dog后边给加一括号,括号里边就是它的什么呀,它的负类,我们直接来一个这个animal,那现在注意animal我们就称为dog的什么呀,负类,那这块我们来写一下。
10:38
哎,在定义类的时候,哎在定义类是。哎,类后的,哎可以什么呢?可以在类名后的这个括号中,哎,来指定什么呢?我们当前类的一个负类啊,负类或者是叫负类,或者可以叫什么呀?叫做一个超类啊,或者可以叫做超类,诶那这块或者也可以叫什么呢?也可以叫做一个积累啊,积累基础的鸡是吧,也可以叫做一个鸡累英文呢,我们叫做一个S啊,叫做一个超类,那这个负类是什么意思?那有负类就得有什么呀,有子类,那现在我们这写完了以后,这个animal就是我们dog的什么呀?负类啊,Animal就是我们这个dog的父类,那dog呢,诶,Dog就变成了animal的这个子类,或者叫做衍生类啊,Dog就变成animal的子类,叫做一个衍生类,那这个时候我们来说一下,那父类有什么用啊,有什么用?那注意了,我们的子类。
11:45
子类或者可以叫做一个衍生类啊,衍生类它会什么呢?它可以直接继承我们这个父类中的什么呀,所有的属性和方法啊,可以直接继承副类中所有的属性和方法,也就是说现在注意我这儿定义了一个class dog,我这里边有没有去使用这个,有没有去定义sleep,有没有去定义bug,这这这个这个叫做一个right sleep有没有定义没有定义对吧,没有定义,那这个时候我们来看一下啊,我们来创建一个dog的实例,直接来一个D等于一个什么呢?D等于个这个dog啊,等于一个dog,然后在这我们来print一下这个D,我们来看一下它的类型,我们这一打印,它现在的类型是不是一个dog类啊,哎,Dog类,那现在注意do里边我没有定义run,那我现在能不能掉呢?我直接来一个D点一个run,看效果一直行干嘛了,是不是动物会跑啊,我再来一个D点一个。
12:45
这个sleep我们这一保存一执行,是不是动物睡觉啊,你会发现在地里边我们虽然没有定义run和sleep,但是我在这里是不是确实是可以去调用啊,那这是为什么?这是为什么?就是因为dog这个类从animal那里边干嘛了,继承了这两个方法,继承到了我们这个run和sleep,那这个时候我就可以干嘛了,哎,我就可以不再去重复定义了啊,不再可以重复定义了,那这种方式是不是比我们之前那个都简单呀,哎,都简单,那同学说了,老师你不是说还有一个B了吗?哎,B怎么办?B我可以在这来干嘛呀?哎,我来去定义一个这个B这个方法,那这样干嘛了,我这是不是定义了一个B呀?那这个时候我们说了,这狗的B能不能掉,直接来一个这个B,这一保存一执行,是不是也可以掉,诶也可以掉,那也就是说这个方法是什么,是我们dog自己的方法,Dog自己的方法,而这个run和sleep是什么?哎,是我们的什么呀?哎,我们的这个。
13:45
父类当中的什么,哎,父类当中的方法,那这个就是我们说什么呀,继承也是我们面向对象的什么呀,三大特性之一,那我们来说一下继承的好处。
14:02
我们来说,哎通过我们这个继承可以直接让哎子类获取到我们这个父类的这个方法,诶或什么呢?诶或属性,诶避免什么呢?诶避免诶编写我们的什么呀?诶编写我们这个诶重复性的这个代码,诶重复性代码。诶并且干嘛呢?诶并且也符合诶我们这个OCP这个什么呀原则,诶也就是说他不会去直接修改你那个原来的类啊,原来类,那所以这里边我们就可以干嘛呀,哎所以哎我们哎经常哎需要什么呀,诶通过一个类啊,通过这个什么呀,诶通过我们这个继承,诶来对一个类进行什么呢?诶进行扩展啊进行扩展什么意思,那现在我们这原来就有一个animal类,Animal里边就有两个方法,一个是run,还有一个是sleep,但是实际上现在这个类是不是不能满足我们的所有需求啊,那怎么办?那这个时候我就创建一个新类啊,创建一个新类,比如说这个类我就叫一个dog,这个dog我继承了animal,也就是说我拥有了animal的所有方法,但是我这是不是还有一些新方法,哎,等于说我这个dog是不是就扩展了animal,哎,Dog就扩展animal从义。
15:27
常来讲animal是什么意思,Animal我们说是动物的意思,对吧?Dog什么意思?Dog是狗的意思啊,Dog是狗的意思,那我问你了,我能不能说狗是动物,我能不能说狗是动物,诶没问题,狗它就是一种什么呀,动物,那这儿也可以说什么,我们说了dog是不是animal,诶dog也属于animal,为什么?因为dog继承了animal啊,因为dog继承了animal,所以这个是我们说的一个什么呀,继承,那这里要注意,我们之前说过一个方法,叫做一个is ten啊is intense它可以用来检查一个类,一个对象是否是一个类的实例,比如说我这直接来一个D逗号,一个这个dog,这表示什么意思,这表示检查我们这个什么D,这个对象是不是dog的实例啊,我们来看一下结果,哎,直接来一个flag啊,我们在这直接这应该叫result合适一点啊,Result吧,然后在这我们来打印一下这个R这。
16:27
结果一保存走一个是不是处啊,哎,是true,那这个时候我再复制一下,我这改一什么呢?诶改成一个这个Ann钮啊改成Ann钮,我们来看看D是不是Ann钮的实力,我这一直行也是什么,也是处,也就是说D这个对象既是dog的实力,也是animal的实力,那这里边为什么呀?哎,因为dog是继承字animal啊,Animal是上边的,Dog是什么呀?哎,Dog是下边的啊,那是下边的,好,那现在我有一个dog来了,那假如说我还有一个对象,我还有一个对象是吧?哎,还有一个对象叫什么呢?比如说我有一个对象叫做一个这个哈士奇啊哈士奇就叫一个哈士奇,哈士奇那问你了,我这哈士奇能不能进继承这个dog,哎,能不能继承?诶当然没问题,哈士奇也可以继承这个dog,那这个时候我哈士奇这个类它有没有dog的方法,有有没有animal的方法,也有他们现在的关系是什么,他们现在的关系就上边一个什么呀,Animal啊然。
17:27
然后下边是一个什么呀?DOGDOG下边是一个什么呀,是一个哈士奇,那在哈士奇里边我可以干嘛呀,再定一个方法是吧?诶定义一个,诶哈士奇有什么特独特的方法呀,哎,发哈士奇我们就来一个什么呀,犯傻吧,诶犯傻哈士奇我这来一个这个诶赛啊哈士奇比较傻对吧?诶我直接来一个print哎哎这个呃,好傻呀哎,我是一只什么呀?哎,我是一只傻傻的哈士奇,哈士奇,那这个时候我如果创建一个哈士奇的对象,哈H等于什么呢?哎等于个这个叫什么呀,等于个这个哈士奇,那这块时候创建这么一个对象啊,那这个时候这个对象能不能调调用犯傻诶可以,能不能调用我们这个B,诶也可以,能不能调用这个诶run和sleep,哎,当然也可以,因为它会有那么一个继承的一个关系啊,继承一个关系,那这个就是我们说的一个什么呀,继承继承非常好。
18:27
理解继承就是可以让我们很方便的对我们这个类进行什么呀?哎进行扩展啊,通过继承可以对类进行扩展,但是这个时候就注意了,那有一些情况下,我们有的时候去创建一个类的时候,比如说我来一个class class,我们之前写过一个person p SN person这个类,然后我这来一个pass,这个时候我后边是不是没有写这个括号,哎,没有写括号,那没有写括号它是继承,继承自谁呢?那注意了,如果在创建类时,哎,如果省略了什么呢?诶类名后,诶省略了什么呀?省略了我们这个负类啊,省略了负类,则默认负类,为什么呢?诶为object啊object,所以你在这是不是没写东西啊?诶没写东西就相当于写了一个他,你什么都不写,就相当于写了一个什么呀,写了一个object,那object是什么呢?那注意object是什么呢?是。
19:27
我们所有什么呀?诶,所有类的一个父类,所有的类,诶都继承自什么呢?都继承自我们这个object,那这object是什么呢?它是我们所有类的祖宗啊,所有类的祖宗它是最大那个类,所有的类都继承自object啊,所有的类都继承自object,那这里边我们来看一下怎么证明啊,哎,怎么证明,那这里边注意我们来看一下,直接打开我们这个直接写一下吧,我们这里边有一个方法叫做一个什么呢?Is,诶,Sub class啊is sub classes,那这是什么意思啊,这是什么意思,这个意思sub就是检查一个类是不是一个类的什么呀,哎,一个这个。
20:14
负类啊,你看人家写了return whether class c is sub class什么呀?哎,这个of class b,检查这个C是不是这个什么呀?诶是不是B的一个这个衍生类,一个子类啊,一个子类,那这一块我们来看一下,还有一个叫什么呢?叫做一个A一个呃,那我们这儿就是一个他我们直接来调用一下吧,调用一下我直接来一个is sub class,我先来什么呢?我来一个DOGDOG我们这来什么呢?我们这儿写一个这个,写一个这个animal,那什么意思啊,检查这个dog是不是animal的一个子类,我们直接打印一下。一保存我们这一执行true,那dog是不是animal的子类啊,哎,是没问题,但是我反过来写来一个animal,来一个什么呢?来一个这个dog,我这一执行什么东西,是一个force啊,是一个force,所以这个方案我们来说一下它的作用是干嘛?是检查一个类是否是什么呢?诶另一个类的一个子类,如果是就返回什么呀,返回处如果不是就返回force,那这里边我们可以看一下,那比如说我这来一个啊,我这复制一下这个助调,助调我这来什么呢?来一个object,检查animal是不是object子类,我们来看一下什么东西true啊true,然后再看啊,我们来看一下,再看一个什么呢?我们这儿还有一个这个person,我们来检查一下什么呢?诶这个person是否是object,是否是object子例,我这一检查是不是也是true啊,诶,也是true,我就不一个个检查了,注意了,所有的类都是object。
21:54
子类,你随便创建一个,你不写这个东西,默认就写了一个object,它就是什么呀,Object子类啊,所有的类都是object的一个子类,所以如果你拿这个对象和object做检查的话,比如说我来一个is in ten,我来什么呢?D来一个object,这是true,是false,哎,我这一执行是什么呀?是true啊,是true,我再来什么呢?我们这还一个这个哈士奇对吧,我一执行干嘛也是true,甚至我直接来一个print print是不是一个函数啊,哎,一个函数唯一执行是不是true啊,哎,也是true啊,也是true,所以这个时候object,你所有的对象和这个object做这个is instance时候都会返回处啊,那这块我们再强调一下is instance。
22:41
Is instance它用来干嘛呢?哎,用来检查一个对象,哎,是否是一个类的什么呀,实例啊,用来检查一个对象是否是一个类的实例,如果这个类是什么呢?诶是这个什么呀,是这个对象的一个负类,它也会什么,也会返回处啊,也会返回处,那如果什么呢?如果将一个这个对象,哎,注意了,所有的对象,所有的对象都是我们这个object的什么呀,实例啊,为什么?因为object是所有类的一个负类,那反过来说,那我们这个所有的对象是不是也都是object的实例啊,所以你将所有的对象和object做这种is instant的时候,都会返回什么,都会返回处啊,都会返回处,这1.1定要记住啊,一定要记住好,那这个就是。
23:42
这是我们说的一个继承,那继承最简单的用法就是这样,它可以让我们省代码啊,你可以用一个这个继承来减少我们代码的一个这个开发啊,减少我们代码的开发,那这个时候我就要提一个问题了,的确继承是减少我们的开发了,减少了我们对代码的一个编写,但是这个时候我们产生了一个这个。
24:06
疑问什么疑问呢?那现在我这里边的确是有bug了,的确是有这个犯傻,应该是犯傻,对吧,犯傻,然后呢,假如说我在dog里边也有一个方法,直接定义一个什么呢?哎,定义一个,我叫做一个re,调用了定义了一个方法,我们这直接来一个print print,我们这来什么呢?哎,来一个这个狗跑,哎狗跑写这么一个,那现在注意了,Dog里边也有RA,它的负类animal里边也有RA,那我当创建dog实例的时候,我去掉RA,那到底是找副类还是找他自己的呢?到底是找谁?诶这个东西我先不说,自己去测试一下,待会我们来讲这个东西啊,待会我们来讲这个东西,来我们先停一下。
我来说两句