00:00
好,那么接下来的话呢,咱们讲一个关键字,诶这个关键字呢,叫做super啊,这呢就相当于是我们讲的面向对象的三条主线里边算是第三条啊这个前面呢,我们讲过这次关键字了,这里呢,我们来讲一下这个super关键字啊,他俩呢在使用上呢,诶大家呢,可以对比着去做这个理解啊,为什么这么讲,诶我们讲到这个super之后呢,你就知道了啊。呃,然后呢,这个super呢,实际上呢,它也得是基于我们讲的这个继承性,诶讲完继承以后呢,我们才能够去理解,哎这个superper,因为呢,Superper呢,其实翻译为呢,就叫做负类的。哎,所以没有继承也就不会有super的使用,好,那这块我们首先上来,哎通过这样一个问题呢,引入说为什么需要super呢。啊,为什么需要呢,调用父类中的呃结构呢?呃这块我们抛两个问题啊,这个我就写个举例,比如举例一说呢,这个呃子类啊,继承父类以后。呃,然后呢,对啊,负类的这个方法呢,进行了重写。啊,这呢是我们一个大前提啊,那我们说呢,诶那么。
01:01
啊在啊子类中说是否还可以对父类中被重写的方法进行调用?诶进行调用,诶你看啊,我们前面讲重启呢,也称为呢叫覆盖啊,所以你此类呢,把负类方法给覆盖了,那导致我们此类的对象你再调方法的时候呢,其实都是你覆盖负类以后的那个方法了,所以那如果说我们要有需要,呃,再在子类里边去调负类中被重写那个方法怎么办呢?诶,就像我们刚才那会儿呢,做的这个题目哈,说呢,在这个圆柱里边,圆柱里边呢,本来我们写的叫呃范德呢,乘以这个高啊,原来的范德尔呢,就是负类里边的那个方法,就是底面面积了,所以现在你给重启了,那导致我们这块呢,就不再是负类这个方法,如果现在我就想用。怎么办?诶这块呢,我们说呢,诶面对这种场景呢,我们说首先可不可以呢?哎这个首先呢是可以的。啊,那怎么办呢?其实呢,就得使用super。这呢是我举的第一个例子啊,哎,我再举一个场景举例二啊说呢这个哎此类呢,继承父类以后啊,有了这种继承关系了啊说呢,哎发现。
02:07
诶发现什么呢,发现呢,这个子类和父类中啊,定义了叫同名的这个参数,呃,同名的叫属性吧。哎,那么我们呃是否可以呃在子类中。啊,去区分啊,两个同名的属性。诶注意哈,咱们这个属性如果同名的话呢,它不存在覆盖之说,方法才可以覆盖属性不能覆盖,那YIG呢,就是我们这个子类集成类以后呢,如果说啊类里边有个属性呢,叫ID,子类呢,又额外的定义个属性恰好也叫ID。那么我们这个子类对象,如果造对象的话啊,哎,子类呢,如果造对象的话呢,其实在内存中呢,就有两个ID。那这个大家要注意一下,属性不能覆盖啊,那既然有两个ID的话呢,这就涉及到问题,那我们怎么去区分两个同名的属性呢。说是否可以区分呢,那显然呢是可以的是吧,那如何区分,那也得用我们这个super。
03:04
所以下边就涉及到我们这两个结构呢,如何去调用呢?哎如何使用呢,那我们说呢,需要使用啊叫诶super关键字。哎,关键字啊即可啊。好,那这呢,就我们引出来这个super关键字的它的一个使用的场景了啊,诶做这样的一个区分,所以呢,关于super理解呢,我们就把它理解为呢,叫做富累德。哎,这样一个词就行了,所以说呢,如果你想调负类中被重写方法,你就调super点,那就表示负类的方法,哎,如果呢,你想调父类中的那个ID,那我们就用super点表示负类的那个ID。那没有写的呢,就认为是你自己,呃,子类里边的这个重写的方法和子类里边生命的那个ID了。诶,所以这样一说的话呢,其实诶就比较好理解啊,那通过刚才这样说明,我们就发现呢,这个super克能调什么呀?呃,一方面我们发现呢,可以调这个属性。啊,可以调这种方法,诶,除此之外呢,还可以来调这个构造器。对,从那个角度来讲呢,跟我们这个这次啊看就比较接近啊,这次也能调属性,调方法,调构造器。
04:06
OK啊好,那么具体来说的话呢,我们就先考虑呃使用super呢,我们来去啊调用这个属性,哎调用这个方法,然后呢,我们说完之后呢,再去讲,呃修复呢,来调用这个,诶构造器的问题。好,先来看这个第一类问题啊,那第一类问题的话呢,我们就直接呢,呃,引出这样一个具体的这种场景啊。好,那么这个场景的话呢,我们实际上呢,还是依赖于两个类,比如person和student啊,那这两个类的话呢,咱们前面讲这个。继承这个测试的时候呢,其实我们用过这两类,我我把这两类呢,咱们就直接粘过来啊,我稍微的改造一下来说明我们这个super的一个使用。好过来啊,诶过来以后的话,我这样的啊,这两个方法呢,我就留着了啊,剩下这些呢,暂且我就都先不要了。就是两个属性两个方法啊没问题啊好,那么在这个student那块呢,这个咱们就把它呢,就先干掉了啊。这个G乘以负类以后呢,额外的我们又定义了一个属性啊,这两个方法呢,我们就拿掉了啊。
05:03
好,这个我也把它就干掉了。行,这呢是一个study一个方法,这呢属于这个student自己特啊这个特有的一个方法了,好那么在继承以后啊,我们这个student呢,就可以对person中的这个方法两个,一个呢叫it,一个叫sleep呢进行这个叫重写了,哎我就把它呢CTRL一下。回到student那块,哎,在这儿我就给大家做一个重写,这块我们说一个呢叫哎,学生。哎,比如说哎要多吃啊有啊营养的是吧。哎,这个食物。好,这个呢叫sleep啊。哎,比如说这个,诶学生。啊,学生是吧,哎,保证啊每天。哎,比如说不低于。八个小时少,比如十个小时啊。哎,这个睡眠啊,对,这个也看年龄啊。这个像小孩的话呢,确实得多睡一睡是吧,这个一个长身高,再一个呢,就是这个。长大脑是吧。
06:00
你看我家那孩子现在这个,反正现在小孩好多家家长发现也都是哈,一整都十一二点睡。啊,我就天天跟他妈说,我说你得让他早点睡,要不以后很麻烦是吧,养成习惯了啊行啊,哎,这儿呢,我就把父类中的这两个方法呢,你看就进行了,这个叫重写了哈,好,那么重写以后呢,很自然而然的哈,咱们如果说在这个测试类里边啊。那student的一个测试哈。啊写明方法,这呢,我们就直接呢造这个此类的对象了。哎,造完以后的话呢,我通过它呢,去调了E的方法,那毫无疑问呢,都是你子类重写复类以后的这个方法了。哎,这都是学生的这个事情啊,哎,关于我们这个sleep呢,也同样的道理。Sleep啊它啊好,那么现在的问题呢,就是说我们怎么在这个此类的这个方法里边,我还能够去调用负类中被重写的方法。注意,咱们现在指的是在此力里边,你别在这儿哈。你在这块是不是能掉这个呢,咱们一会儿看啊,哎,先说呢,是在子类里边,比如说啊,我现在呢,有一个普通的方法。
07:03
哎,我就假设就叫它瘦了啊,这个方法里边呢,现在我写这个it。那么毫无疑问呢,这个it是不是指的是它呀。对,那就我这块要调的话,肯定执行的是它了啊,哎,那这个呢是他了,然后如果我要这样写呢。还是他是吧,或者换句话说呢,你没有写前面这个谁来调,其实相当于省略的就是Z4是吧。这个所以说呢,叫省略了这个Z啊这个结构了,所以这俩呢,其实没有任何区别啊,那如果说我现在就想调负类中的这个方法,诶非常简单,你就super.it就可以了。哎,这样就行。当然了,这个能调的前提呢,是你这个权限也得够哈,你光想着调那权限都不够,那你肯定也调不了,所以说这个调用呢,它也得以不影响封装性为前提啊,那由于我们傅雷这个呢是public嘛,所以我这块就能调啊。诶,这样就写了,写完以后回到我们测试这块,哎,咱们再拿着S一点,咱们去调这个收方法。
08:00
好,那么我们这块呢,做一个执行。诶OK啊,这块稍微的有点长了,就这块啊,这个收方法里边呢,诶,我们首先叫it,这是你学生自己的啊,这点it还是它,然后呢,super.it就是负类的这个方法了。呃,其实呢,就比较的清晰。OK啊。好,这呢是我们说的这个事儿哈,呃,那么如果说在父类当中呢,它有一个这样的方法啊,比如说我们这public还我这个人的话呢,还有什么样的方法。运动啊,行,Do sport。来运动啊。人。来人运动好,那么这个方法的话呢,我们在这个此类里边,我没有重写哈,我没有重写的情况下呢。哎,我这再比如换一个啊。Public我就要收一了啊。所以在这里边儿呢,我现在调这个叫do sport是吧。哎,那么这时候你说掉的是谁的呀?毫无疑问是负类的子类,你也没重写是吧,那么这时候我们前面这个前缀,这算是什么。
09:05
对,注意这时候呢,只要我们前面没有写这个前缀呢,都省略的是这点啊。诶do sport啊,相当于我们前面呢,这个呢,就省略了this了,这个时候呢,我们要是加上这个this的话呢,就是我们调离方法时候呢,它又调用了你诶本类当中的另外的一个方法,那他呢,先会去在我们student的这个类里边呢,去找看有没有这个方法。找的时候呢,没找到。没找到呢,他就会接着去他的父类当中去找。那么负类呢,就找到这个person了,哎,Person里边找到了,所以这时候我们诶调的其实就是负类里边那个SPA这个方法。那这呢,我们是只有两层关系啊,那如果说我们这个子类里边调了一个方法,在自己这个类里边没找到,他先去这找这如果也没找到。哎,就再往上找,哎,这也没找到,再往上找点点点找到哪。找到object。对啊,找到object,如果呢,找到object的时候呢,还没找到。
10:03
他就会报错了,说没有定义过啊。哎,注意是这样的,哎,那言外之意什么意思呢?举个例子啊,我这有个方法叫A。这个方法A呢,这个呃,子类呢没有重写,然后这个子类呢给重写了。注意重写了啊,那这里边儿呢,如果他也重写了。那这时候呢,你要是这次点去掉,是不是就掉它。啊,那如果说我没有,呃,重重写,或者说我这边我写的叫修点哈。哎,修破点的时候呢,是不是它就诶略过你当前这个类。哎,直接找负类,负类的注意是找这啊,哎,如果找的话,一找找到了。那就用它了,哎不会再往这儿,你说诶怎么去区分这俩呢,不用考虑区分它就是区块呢,就是从直接负类在往上一层层找,只要我找到了,我就停下来了。哎,这样的一个场景。诶,所以说我们这里边诶,就只有一个读SPA的啊,也没有做这个重写之说,所以呢,这块你省略了写上这次啊,从这个结果上来看呢,诶跟我们。
11:04
哎,这样写呢,其实是一样的。那当然你注意呢,真实的过程呢,他先在本类找他呢,是直接就奔着直接父类去找了。诶,所以呢这块呢才会体现出它俩的区别啊,这个呢直接在本里找找到了,所以呢我就不往上再翻了,所以这个呢就调呢重写的了,而这个呢,就直接略过你当前这个student上来就找傅雷了,哎,所以呢就找的叫被重写的。哎,这个方法了。哎,就是我们说的这样的一个场景啊好,那这儿呢,我是以方法来说的,呃,相当于呢,解决的是我们刚才说的这个这这一类问题啊。好,那这个解决以后呢,我们接着看下一个问题。说呢,我们在这个子类和父类中呢,万一要是定义了同名的属性了怎么办?比如说在person里边,诶我们这儿呢,就定义一个,诶这个我就暂且不考虑这个权限的事了啊,我就写那个叫ID了,这个呢,我们可以理解为呢叫身份证号。身份证号好了,然后呢,我们在这个student这里边呢,我也在定义一个啊ID,哎,我就叫ID啊。
12:08
哎,这个ID的话呢,我们理解成了叫学号是吧。诶,首先呢,我们要明确一个问题,就是在我们创建完这个student以后呢,它到底有几个属性的事是吧。哎,P在里边呢,这算是撒。指定那里边儿呢。俩是吧,哎,这算是,呃三加二是五个呢,还是说我们应该把重复的这个给干掉呢?哎,注意五个啊,你看还是我们打一个断点,这个我们来一个第八个。好,这时候我们点往下走一步啊,这个IC这个对象呢,就创建好了,然后我们这块打开,哎,大家你看啊。Name。啊,Age和percent ID,这是你类的。哎,这仨,然后呢,这俩是你自己的。诶,他呢,为了区分出来,他在这块加了一个percent里边的那个ID是吧?诶所以呢,首先呢,明确一下,我们这个属性呢,是没有说像方法一样有覆盖指数的。
13:02
啊,这个我把这个呢就让它结束了啊,属性这块呢,不会覆盖方法才会,所以呢,我们这里边儿ID呢,在内存中首先有俩,好那有俩了,问题是我们如何区分。啊,这块我们接着来是吧。这个为了我们好演示呢,我在percent这里边给它赋个值。假设呢,这个就是1001啊。然后student这块呢,给他来一个1002。诶,这个为了就是方便我们去说明问题啊好,下边我们还是在这块呢,去做这个测试啊public。哎,我来个数二。哎,就整个呢,咱们这下边儿这块啊。都是来来测试。哎,这个super。哎,他来调用方法和这个属性的啊。好,那么这个数二里边呢,诶现在呢,我们就想去打印一下这个ID了。哎,我就直接这样写的,那么哎负类里边1001此类呢,1002问这时候它是多少。
14:03
1001还是1002呢?啊,这个大家意见就不一样了哈,哎,首先呢,明确一点,他没有编译报错哈,编译呢没有说说,诶我这个区分不出来你这个ID是谁的,他没有。啊,没有的话呢,其实大家呢,你就记住一个事儿。他会有这种所谓的叫就近了。啊,你往哪想呢?你看咱们写那个盖塞的方法的时候呢,不就是有这样特征吗?你看我这个public,我写个word,我叫side,一个school。你看我这呢,写一个死钝形的一个故。哎,在这里边是吧,你说我这里边儿我写啊,School等于school。说他怎么不给我报错呢,为什么报错呢?说有歧义啊,说你看这叫死故,这叫死故分不出来了,没有编译器说我能分出来。哎,他呢就就近了是吧,哎,他就认为你这俩呢都是他,但你这个位置,你说我叫死故意啊,那不好意思,这块咱不一样,那我不就就近也不是你,那我就找我这儿。他就认为这俩呢都是他。哎,所以呢,就是诶当初咱们讲这个时候呢,这不是前面得来个这次点嘛,是吧。
15:03
里边涉及到呢,就有这种就近的这种原则啊,哎,这呢属于一个呃,默认的一种场景,说白了就是这俩的地位不一样啊。呃,地位不一样的时候呢,我就默认的有一个选择,那这儿呢,也同样的道理,我这个ID的话呢,呃,父类有一个,此类有一个,首先呢,没有歧义,没报错,没报错的话,你就想就近,那就近是不是就就自己了。所以这时候呢,这个写法说白了就跟我们这个写法呀,又是一样的啊。哎,所以这时候我们找的话呢,跟方法一样,先在自己这个类里去找一找,找到了,所以我就1002了。这个呢,诶跟上面这个完全一样,只是省略了C4而已啊,那如果说我现在我就想找负类那个。对,那你就哎super.id就行了。他呢,就是1001。哎,这个呢,叫12来回过来。在测试这块我们看一眼啊。先打印一下。S一点收二。哎,运行。
16:00
好,你看这个呢,跟我们想的呢,是一样的道理啊好这个呢,我们说清楚了,然后呢,再回到这个student这块啊,稍微的我们再左手两句啊,诶我们在public。哎,我的我们来一个这个受三是。这里边儿呢,我们提到这个ID呢,是他俩呢,确实啊,这个负了一个子类一个,那那如果说现在我们调的这个呢。嗯,这个A这块我们权限不够了哈,这个我们就以name来说吧,这个name的话呢,你看我这块直接打印这个name。哎,这个时候呢,这种写法啊,大家你永远记住,只要这样写的啊,就相当于省略的是Z。所以呢,我们这个name的话呢,它先在当前这个类里边呢去找啊,没找到是吧?啊,那么没找到的话呢,它就蹦到负类里边去找了,负类呢一找person找到了,找到了之后就用你person里边的那个纸了。诶,所以呢,诶在我们从结果上来看的话呢,跟这个写法他们仨的值其实是一样的是吧。哎,但是你注意呢,就是在找的过程上呢,有一个区别。
17:00
哎,就是他先在本类中的找,而这个呢,直接就奔到负类里边去找了。OK啊,所以呢,我们加super跟不加super啊,不加super就是这次了啊,区别呢就在于说呢,你要有同名的了。或者这个方法呢,这块出现这种这没重写的还行,出现重写了,哎,这个它的意义就出来了,如果说没有重写。没有同名的。其实加不加是不是。都还行是吧,从结果上来讲是一样的,只不过呢,就是一个是现在本类找,一个直接奔着负类找啊有这样过程上的一个区别,但是结果没区别。好,这块我们回过来就做这个总结了啊。下面来说一下啊,用虚分呢来调用属性和方法啊,说呢我们这说呢这个哎子类。哎,继承父类。诶父类以后,诶所以这儿呢,你能看到我们的修克关键字呢,要想使用的大前提啊,都得是基于继承啊子类呢,继承父类以后呢,说我们就可以啊在呃此类的这个哎方法。或刚才呢,我们又拿构造器来说啊,此类的方法呢,或者哎构造器中哎叫哎调用呃附类中声明的这个呃属性或方法。
18:10
当然这块呢,我有个大前提啊,得是满足封装性的前提下啊。就相当于你你想调,你别权限不够了啊,这个权限够了你才能调。这个调用时是吧。哎,需要呢。哎,使用啊,这个我们叫super点。哎,使用super点啊这样的这个结构啊,然后呢,表示调用哎负类的这个属性哎或方法。能不能理解啊,就是这呢,说我们在这个里边呢,可以去调用这里边儿这个结构,哎,这块应该这样说哈,说如何调用呢。哎,这个我们说需要使用这个结构。哎,这呢,我们说的,哎,但是啊,一般情况下呢。哎,我们可以考虑呢,省略。
19:00
哎,这个休克点这个结构。这个我就别但是了啊,就是一般情况下呢,我们可以考虑省略这个结构啊,但是。如果出现啊,这个嗯,子类啊,重写了父类的方法。啊或子类。啊和负类中。呃,出现了叫同名的属性时。哎属性时啊则哎必须呢使用super点这样的一个声明。啊,显示的。啊,调用。啊,调用呢,就是父类被重写的方法,哎或呢,这个父类中。哎,这个声明的这个同名的这个属性。哎,这个能理解吧。对这呢,就我们刚才说的这样的这个场景啊,大家把这个事儿呢,给大家记住啊,嗯,其实呢,比较简单。啊就过了啊呃,然后呢,关于属性这块呢,我们多说一句啊,这里边儿提到了说此类负类中这个同名的属性了,这个大家在实际开发当中啊,一定要避开这个事。
20:09
哎,你别自己给自己找麻烦啊,我这块呢叫ID,你这块呢,哪怕你叫student ID都行。啊,你要不避开的话呢,这个就给自己设置障碍的。啊,这个要注意一下,在我们这个课件里边呢,你看我这里边儿也写到这样问题了啊,关于呢,属性这块调用的问题。嗯,这个应该在上边了啊,在这啊。在属性调换的时候呢,这个阿里呢,它不是有这个相应的规范,诶我呢在资料里边也给大家发了哈,在这里边儿呢,有一个点他就提到说避免在此附列当中啊,成员变量之间,或者不同代码块局部变量之间呢,采用完全相同的命名。这样使得我们这个可读性呢就降低了。哎,这儿呢,其实说的这个就是刚才这个问题啊,大家要避开这个同名的事儿。啊,要不给自己设置麻烦啊,但是对于方法这块的话呢,没法避开方法的话呢,我们是一定会出现这种重写的场景的,那你要调负类中被重写的,那你就加修点就可以了。
21:03
啊,这个我们已经说清楚了,然后接着的话呢,我们再看一下super呢,调用构造器的问题啊,似乎的话呢,我们说调构造器呢,包括我们上面说为什么要使用super,都没有提到它调构造器的事儿。而且呢,我们好像说呢,是不是可以不调呢,是吧,啊为啥非得调过道器呢?哎这块我们说呀,如果呢,我们不接触啊,休克高调用过道器的问题,我们其实就哎看不到,呃对象实例化的完整的面貌,或者叫完整的过程。哎,什么意子啊,哎,举个例子啊,你看咱们在这个位置呢,我用了一个student一个对象。然后呢,我通过这个呃,S1这个对象呢,我们可以调一些方法,你可以说呢,这些方法呢,我们调的都是呃子类重写负类的,但同时的话呢,呃,如果父类中的举个例子啊,像这个属性我们没有加这个权限的限制,那其实呢,我们在这个测试的位置啊,我通过这个S1,咱们呢是可以来调这个内幕的。啊,是没有问题的哈,呃,那就相当于是我们,呃知道呢,在内存中是有这个内幕属性的,所以我就可以掉,这样说呢,也没毛病啊,因为继承性在这兜底呢,是吧?哎,当然呢,我们会问说为什么我们knew的是一个student。
22:11
啊,相当于呢,你调的是student的构造器。那我们会加载student的这个结构,毫无疑问,当然你为什么还会加负类的这个这个结构呢?是吧?哎,那只有呢,解释了你加载了负类结构这个事儿,我们才会知道为什么在内存中会有内幕这个属性。哎,那为什么会加载复力的这个结构呢?这呢其实就涉及到了我们修复调用构造器这样的一个问题。诶这呢,就提到这样一个场景了啊好,那这块的话呢,我们描述的话呢,咱们可以看一下这个课件。诶,关于子类构造器当中调用负类构造器的问题啊,这呢我们一共写了有六个点啊,咱们呢一个一个来看啊,首先第一个。哎,把它拿过来啊,说呢子类继承父类的时候呢,不会继承父类的构造器。咱们前面说过了,构造器你得在你自己这个同名的类里边才有的哈,哎,但是的话呢,我们在子类当中可以通过叫虚块形态列表的方式呢,调用负类的指定的构造器。
23:07
诶这个是没问题的,比如说在这个顿里边呢,诶我们暂且的话呢,是没有写任何的这个构造器的,好,我在下边这块吧。哎,我们来呢,去测试这个super这个形态列表的方式啊。哎,或者直接这样啊,Super呢调用哎副类的这个诶构造器的问题好,首先的话呢,这块我写一个叫呃,Student。这呢是一个具体的构造器了,哎,这是一个,咱们再来一个啊。Student。然后呢,在这里边儿呢,我们写上比如说a string性的一个name啊,性的一个age。好,我加上这样的这个属性核散这块呢,构造器咱们这块也没有写具体的啊,我这块呢,稍微的提供一下啊。哎,首先哎,我在负类这块呢,提供一个比如说空单的构造器。呃,提供这个代餐的,代餐的我们整一个,比如这两个的一个啊。
24:00
哎,再来一个吧。哎,再来一个,比如说三个的,嗯,好,然后呢,在负类里边呢,你看我定义了三个扩导器,然后呢,在student那块呢,哎,我写了空三呢,写了一个两个参数的,好,就以这个为例吧先。然后这个里边呢,我们看没有写任何的信息啊,然后呢,现在我们就显示的这样调一下,哎,我这写的叫虚沃空,哎,通过这样的方式呢,咱们调的就是负类当中空餐的这个构造器了。也就意味着我们一定会掉这个构造器,比如说在这里边呢,我写一句话啊,我呢叫做a person。点点点啊,然后在这块呢,我们也写上一句话。啊,这个叫a student啊点点点。好,那么写完以后呢,我们回到这个测试这个层面,呃,上面这块呢,比如说什么样,咱们就不管了啊,咱们下边呢,重新呢再去啊写具体的这个测试。啊,这让我来一个换行啊,然后呢,我们再去创建一个学生的一个对象。那这个呢,我就S2了,好,那么此时的话呢,我们看一看这个执行的情况。OK啊,然后在这个空格的下边啊,你们会发现呢,当我们调用这个子类构造器创建对象的时候啊,它呢,首先调了虚空,那就调了我们这个构造器了,所以呢,这块呢,这个person呢就打印了。
25:08
然后这个打印完以后呢,它就调用结束,我们再回到student那块,再把这个它呢做了一个输出。那继而的话呢,我们这个对象呢,哎,接着就创建完成了。诶,首先呢,我们先提到了,我们可以呢,在构造器的这个子类的这个构造器当中调用浮力构造器格式呢,就是它。啊,这倒是我们说的第一个基本的点啊,好,然后接下来看这个。啊,第二点说呢,我们要是想写的话呢,这有一个要求说这个修复呢,形态列表这个结构啊,要写你也必须写在这个子类构造器的首行。哎,那就意味着啊,像我们刚才这块写这呢,就放在首行了,这个呢,哎,相当于第二行,你要试图呢,把它俩颠倒一下,哎,这块呢,它就报错了。哎,这块看写的说你必须呢,是在你这个构造器这个题里边的是第一个语句才行。啊,这样我们就必须呢,把它颠倒过来才可以。哎,那么这一点的话呢,是不是跟我们那个这就有点像了。
26:03
哎,这次呢,我们写的时候也是这样的要求哈,好,那有了这次这样的一个提前的一个一个知识点,那这块呢,你看我们说啊,两个人合在一起,就会有这样的一个结论。哎,看大家能不能理解啊,说呢,我们前面讲过,说呢,在构造器的首行呢,可以使用这次形态列表这种方式呢,表示调用本类中重载的,呃,其他的构造器。啊,你掉的肯定不是自己了啊,掉的是其他构造器了,好,那现在的话呢,我们又说了一个super,他们俩人要写都得写到首行,那我说下得到这个结论呢,就是说在一个构造器的首行。哎,你要么呢写的是Z,要么呢写的是super,他俩只能是选一个。不能俩同时出现。哎,对的啊,哎,就相当于我们在这个student这块啊,现在呢,我写了秋克了,你就不能在这块试图再去写个C。啊,所以这块,比如我用下边这个啊,我这里边给你传个值,这个叫汤姆,这个叫12岁,哎,不好意思不行。
27:00
啊,因为这时候呢,它就成了非首航了。哎,所以这两个的话,我们说只能是存在一个。啊,这正是我们说的这样一个结论。不能同时存在。好,这个呢,我们先明确了啊,然后呢,我们再拉回来看下边这个点。哎,这个我们再转过来。这个啊。嗯。啊这个啊说呢,如果在子类的构造器的首行,我们呢,既没有显示的调用这次心态列表。也没有显示的调用super形态列表,就是说我俩都没调啊,都没调的时候呢,问此时呢,我们是一个什么情况呢。这块说了说则啊,这个时候呢,此类呢,其实呃,默认呢,会调用修复空参。也就是说呢,我们一定会调用负类中的啊这种场景哈。轰参的构造器。啊,这个啊,回过来还是看这个student啊,Student这块呢,咱们显示的调的是负类中的空三的过导器了。那这个位置你发现我是不是没有掉啊。
28:00
哎,这个位置我要是没有调的话呢,我现在就拿它来创建一个对象,大家看一看啊。回到这个测试这。哎,下边呢,我们再比如换一个行啊,哎,我就student s3了。啊,你有一个student。这个呢,比如我们就叫做这个汤姆啊,这个12岁好在此时在咱们使用呢,就是这个构造体,这个构造器里边你看似什么也没写,那么我们在运行的时候呢,你看看它会不会有输出的结果。转一下。诶,但是你发现你看这不换行,后边这有一个他吗。你说是它吗?是它啊,这块你在这块呢,可以加上这个双引号,我们整一点这个星是吧。在这儿比如加点这个星好,你看呢,看一下呢,在这个星的后面啊。那这不就输出了吗?哎,那就说明呢,我们这个构造器呢,你首行呢,我既没有写这次形态列表,也没有写super形态表,那么这时候呢,我们说默认呢,就是super形态列表,而且是空餐的。
29:01
所以呢,它会把我们person里边的,诶这个构造器呢,调用一次。如果呢,大家你想通过这个debug的方式去看的话呢,那也可以,那我现在加一个断点啊,诶我们右键来一个debug。诶过来了啊好,那么这时候的话呢,我们想看一看它里边这个代码是如何执行的,诶这个时候的话呢,我们点第一个就不行了啊,如果要点第一个呢,它就直接呢就进到下一行了啊,那要再执行这不就结束了吗?哎,那我这块这样啊,我重新再再把它抛起来。抛下以后呢,我们点后边这个,这叫step into,就是进入到这个代码里边啊,你比如说你这是个构造器,我就进到你这个构造器里了啊,所以点一下诶,大家你会发现呢,是不是就走到这儿了。诶走到这儿的话呢,你看我现在我再去点一下。你发现他是不是这时候就跑到person这了?诶,所以这块呢,给我们的提示就是说我们在啊,你调这个student的这个构造器的时候呢,它默认的啊,如果没写this也没写球呢,他就直接的默认调的是person里边这个空参的了。
30:02
所以呢,接下来我们走下一步。啊,下一步这块其实这个就是细节了啊呃,涉及到了我们这个里边的这些属性的一个初始化赋值的问题了,呃,然后呢,这个person执行完以后,然后呢,这个回到这儿来,把这个student执行完了,然后这块呢回来这就算是到结束的位置了。哎,这就整个这样的一个场景。OK啊,诶所以呢,诶我们发现呢,它是可以调修克的啊,如果说你看我把这个person里边的这个构造器,但是你看啊,我把它给注释掉了。相当于这里边儿就没有空难构造器了,那么你回到我们student这块。你会发现呢,这个位置报错啊,那好理解,因为你调空弹没有嘛,是吧,但是他也跟着报错了。能理解吧?呃,因为呢,他是不是调的也是空餐呢。诶对的啊,诶你看这块儿说你这个,诶没有指定一个可获得的这个默认的一个构造器,就是这块你也没有显示的调负类的谁,那我就调空的,但空的你又没有,哎,他就报错了。OK啊,所以我们把它这个打开,那这块呢就就没错了。
31:01
好,对应的结论的话呢,就是这个这两个结合在一起。啊,你看我们能得到一个什么样的结论呢?CTRLC。拿过来。哎,就是结合这个三和四哈,你看我能得出这样的结论,这个结论呢,大家可以记一下啊,说呢子类的任何的一个构造器当中说啊,你要么呢,是调用本类中重载的构造器的。所以要么呢,你就会掉负类的轨道漆,只能是这两种情况之一。你看对吧。啊,这个稍微有点难了啊,大家你看啊,我在这个此类的任何一个构造器当中啊,比如说这是person,这个是student student里边的假设啊,你看我这呢,我就哎抽象点,这有三个构造器了。参数呢,肯定都不一样。哎,那这个构造题来讲,咱们前面说过了,说你首行可以写,这次写代表也可以写super。写了这次了,就没有super了,写了就没这次了。
32:01
是这意思吧?也就是说呢,你构造起的首行,呃,你要么你显示写了。写这次的行是吧,要么你显示写super了。呃,那另外一个情况呢,就是你没写,这次也没写。那是不是还是super呀?所以这块我就说啊,说你在构造机首航啊。就是我说呀,一定会存在这次新列表或修复新单列表的。只不过呢,就是呃,是你显示写还是没显示写的问题了。是这样吧。哎,对,记住这样的一个结论啊,这个结论呢,是由我们这个A3和四呢,这边合在一起的。而且呢,你要是写的话呢,我们说呢,也只能是写一个是吧,因为大家都要求是首行,所以你只能出现一个。啊,这样的一个场景,OK啊行,那由这个出发的话呢,大家你再看这个结论啊,这里边儿这个一行一行的这个逻辑呢,是非常的严谨的啊。哎,你看能不能得到这个结论啊,说有这个五又得到个结论说呢,如果一个类当中声明了有N个构造器。咱们前面说过,说最多呢,你有N减一个呢,使用Z。
33:04
啊,因为呢,你要是都N个有的话,一定会形成个环跟递归一样不行是吧?哎,这咱们前面说过这个事儿了,那有一个就是说最多有N减一个啊,那你是不是说就是最起码得有一个没有用它呀。那最起码有一个没有用,那没有用的那个呢,就一定是写super。可能是你显示写的,也可能是默认的。你想对吧。啊,这个里边呢,这几个啊,逻辑呢,推论是非常的一个挨一个的,非很很严谨的哈,你那由这五得到的结论呢,就是构造器的首行一定会有,这次会有super,那现在说你最多有N减一个Z次了,那剩下的就一定是super。没问题是吧,所以呢,在实际开发当中,我们看到呢,会是这样的情况,这呢是一个负类啊,这个细节呢,咱们就不说它的过到期了,这呢是一个子类,这个子类的话呢,诶你看我这块呢,假设有这样的五个构造器哈。那么构造器呢,咱们说呢,可以彼此之间去掉,那就是这次的情况啊,我这个构造器呢,掉它了。
34:05
他呢,可能又掉它了。当然它呢,还可能调它这个的话呢,说诶这个还可以掉它是吧,这个我说啊,一定不能再往回去掉这次了。咱们前面讲过,一掉就成了这个环了是吧?哎,那这个呢,是不是一定那就是掉修复了,是不是它就掉这儿了。那就这样。那那你看我们一个实际情况,假设呢,我通过这个构造器呢,造对象。这个构造性能会掉它,它又掉它,它又掉它,它就掉它了。是不是就掉负类的这个构造期了。哎,对的哈,好,呃,这呢是一种场景,这个你随便挑一个构造器,在我们这种场景下,你随便挑构造器,我说呀,它一定会直接或间接的调用到负类的构造器。在这个场景当中是,那我再换一个场景啊,咱不是这五个啊,还是五个,但是它五个关系变了啊,换一个红色的,比如说。现在的话呢,假如这个构道现在叫它。他呢?
35:01
假设谁也不掉,那谁也不掉,那你就掉休克了吧。你你是不是就上去了。哎,那你要是用这两个构造器其中之一造对象的话呢,我说一定会调用到父类的构造器。行,那这哥仨,这哥仨呢,说他呢说说要不他他就直接掉了啊,也是一种可能性,或者他没掉,他没掉他掉他了,那他呢,他掉他掉他了,这个呢没得想,肯定不能往回掉。比如说那我不调这俩,我这个是不是有可能调这个呀。有可能啊,他要是回过来掉这个的话呢,这个又掉它,它又掉休克了。或者你说我这个就掉第二个,那你这块你这不也就掉super了吗。或者你这块你你往这个不能往这掉,也不能往这儿掉了,这就成环了啊。哎,总之不管你这几个构造器相互之间怎么调,我说呀,你随便选了一个构造器。这个构造器呢,一定会直接或间接的调用到负类的构造器。对吧。哎,是这样子的哈,诶我们把这个事儿呢,可以稍微的简单在这写一下啊,其实呢,就由我们前面这个呢推出来的哈,说呢诶我们在呃,通过此类的构造器创建对象时。
36:09
啊,创建对象时啊,呃,这个一定啊在调用。哎,子类构造器的过程中。嗯,构造器的那过程中啊,直接或间接的。哎,调用到哎负类的构造器。哎,傅雷构造器,哎,那我们调负类构造器的目的是什么呀?诶,注意啊,咱们调富力德构造器的目的啊,不是为了造对象。呃,因为这个对象的话呢,你包括我们看这啊,我现在用了个student,咱们也知道了,你这个new student调这个构造器的时候呢,它一定会诶直接会渐渐的调person的构造期了,但我们调构造期的目的不是为了造对象哈。呃,因为造对象的话呢,我们说你得搭配一个new,所以呢,自始至终呢,我们就只造过这一个对象。
37:01
那你调person构造器的目的是什么呢?对,是为了有一些初始化信息啊,比如我们这里边儿呢,可能有ID啊,在这里边可能会去做一些赋值。诶或者呢,即使你没有显示的做一个初始化,我们也会呢,把这个类的这些信息啊,比如说属性,比如说相关的这种方法给你加载到内存里边。那为什么说我们直接呢,讲我们上面讲的这个例子啊,我通过这个S1啊,看似我用的是一个子类的对象,掉的是子类的轨道器,那凭啥你就能调负类中这个属性呢。啊,其实就是因为呢,你在调用子类的这个构造器的时候呢,你调用过负类的构造器,那调负类构造器的时候呢,我就把负类当中的那些属性啊方法呀,给你往内存中去加载了,也证明你加载了,所以呢,你不才有吗。如果你要不加载傅雷的,你凭啥你来傅雷中生命的那个属性呢?对吧,哎,就是这个道理啊,好,这块我们说一下,直接或间接的调用到负类的构造器啊,也正因为。哎,调用过。
38:00
哎,这个哎负类的构造器啊。哎,构造器。诶说呢,我们才会将。哎,这个,哎,负类中。哎,父类中啊声明的。哎,这个属性啊,或者是方法啊,加载到加载到啊这个内存中。哎,共。你这个子类这个对象使用。诶,就是这样的原因。啊,这呢,就是咱们说出说清楚啊,说为什么我们这个休克尔调构造器这个事儿呢,咱们还是要讲一讲的啊,因为这个事儿要不讲的话呢,其实大家呢,就理解不了我们这个对象呢,整个创建此类对象的这样一个过程的细节了。OK啊行,那么这个结论是什么呢?就结论呢,大家以后呢,再去,诶我们这个声明此类的这个构造器的时候呢,这个构造器的首行呢,诶你就可以呢,去调副类的指定的这种结构了啊比如说你看这个位置啊,这我写了一个student这个name和age啊我就想哎,通过这两个行参呢,把你这个student呢,从副类中啊拿到的这两个属性呢,做个初始化。
39:03
啊,要做初始化的话呢,诶,如果你负类里啊这两个啊做初始化,如果这两个的这个权限呢,还不够啊,如果都写成private了,那你就得去这里边找是不是有这个盖塞方法是吧。比如像咱们这里边呢,这个呢,我就了啊,那你要想去给值,你只能依赖于这里边提供一个方法。哎,这样写的啊,这样写完以后的话呢,你回到C这块啊,你你要是按原来来讲呢,是不是你就得set一下A是吧。把这个A只能放到这儿,然后这个name的话呢。内部这块呢,我这呃权限呢,貌似给的这块大一点,你可以直接调倒行是吧,相当于这块呢,直接呢就怎么写。Name等于name肯定不行是吧?这咋写?哎,这块你写这次也行,写是不是也可以。呃,因为呢,这次呢,它当前这个类里边也没有内幕属性。哎,他就去负类找了,你要写区呢,直接就去负类里找是吧,好,但是这样的写法呢,其实是比较low的哈。
40:02
哎,我们不会这样去写,那我们怎么写呢?在父类它提供了一个这样的构造器的情况下。你看这不有吗。哎,我就直接呢,在这个student这里边儿呢,我们就写一个叫super了。然后把这个name和age呢,我就传进去。哎,进而的话呢,它就直接呢,来去调一下你浮力中的这个构造器了。哎,然后这块呢,不就把这两个属性给初始化了吗。诶,这就咱们平时开发中啊见到的这个场景,呃,你要是不这样写的话呢,它其实呃没掉它它就相当于是调的是这个了。哎,就这样场景,说白了就是你不写呢,他也一定会去调的啊。行,这个关于我们修会调构造器的事儿呢,就说完了,稍微的也有一点难度啊,诶,当然你顺着这个思路呢,往下捋一捋啊就可以了。
我来说两句