00:00
那么刚才呢说了,说多态性呢,只适用于方法,不适用于属性,那方法这块呢,我们把这个事儿呢,叫做虚拟方法调用,那这块呢,大家可能还会有点迷糊啊,说虚拟方法说的感觉就很抽象似的,怎么叫虚拟方法呢?其实就是咱们这里说的这个问题,说有了多态以后呢,咱们编译的时候呢,认为是你父类的这个方法,然后真正运行的时候呢,是你子类重写的这个方法,把这个事儿呢,我们叫做虚拟方法调用,然后咱们再强调一下,我在这个PPT里边呢,有了这样的几个内容。哎,咱们再深入的再让大家再去理解理解,虚拟方法调用上面有一个叫正常的情况。所谓的正常情况呢,就是没有多态性,我声明的是什么类型,我就new,什么类型正常调方法就是你自己的声明student,我就new student就调你自己呢这个方法,然后呢,什么叫虚拟方法调用说子类当中定义了与父类同名同参数的方法,就重写其实。然后在多肽的情况下呢,将此时负类的方法呢,我们就称作叫虚拟方法。
01:07
我们把父类这个方法,就是被重写的这个方法就称为叫虚拟方法,也就是说在编译的时候呢,我们还认为调的呢,是父类的这个叫虚拟方法,你像实际执行不是负类的了,就是感觉这个副类这个比较虚嘛。我叫虚拟方法,这个叫virtual method,有的时候翻译呢,也成为翻译成叫虚方法。虚虚就是虚幻甲是吧,因为你看着是写的它,但是你调的时候又不是它,所以叫成个叫虚方法,哎,将它俩称为虚方法啊,或者叫虚拟方法,父类呢,根据赋给它的不同子类对象,我用的这个对象呢,都是子类对象,根据你到底附的是哪个不同的子类对象,动态的调用属于子类的该方法。也就是说你执行的是你子类重写的这个方法,父类呢,这个写虚的编译时候让你看一下,运行的时候跟他就没关系了啊就这意思,那这样的方法呢,咱们的调用在编译期间是无法确定的。
02:07
就是编译的时候呢,我是不知道说你到底new的是哪个对象的,有同学说,诶这不看到是new个person嘛,呃,你一个student是吧?嗯,这里边其实提到一个问题,就是说这个我们多态的使用,它到底是一个编译式行为还是一个运行式行为呢?诶,应该说是一个运行时行为,就是编译的时候呢,我们这不都叫做一个虚拟方法,虚方法嘛,真正运行的时候,我们是不是才知道你到底是哪个子类对象呀。可能有同学说说你这这不这不也能看出来,这不就是new student吗?这个题目呢,你可能还能看出来,或者说呢,给你解释呢,你容易迷糊,那我后边呢,有一道这个题,说多肽呢,到底是编译式行为还是运行式行为,如何证明,那这呢,一定要说它是一个运行式行为,怎么证明,我这呢写了一个代码,这个代码呢,应该说还是挺经典的,看一下,哎,我我这样吧。
03:08
把它呢,CTRLC。粘过来我就粘到这了啊在这呢,CTRLDCTRL1,然后回车一下,好,Animal快出名了是吧,那我只能是再重新建一个包。把这个呢扔过去。他这还。吊人家干啥?哎,看这啊。说呢,这个多肽呢,是编译式行为还是运营式行为,大家看我这个例子写的说这个animal eat,这个cat dog,这都能继承于我们的animal,这没啥可说的,这是一个羊啊,然后接下来我这呢写了一个这样的操作,我叫get,呃,先核心的话,先核心看这啊,我这个没方法,这个没方法的话呢,我这呢先取了一个随机数。
04:03
啊,取机数next in呢就012啊先取个随机数,然后呢,我打印下这个随机数,接下来呢,我调了一个叫get s这个方法,这get s方法呢,把这个随机数呢放进去,放到这里边看一下你这个随机数是几,是零是一或者其他,那就二是吧,哎,你是不同的值,我就用不同的对象。啊,New完不同的对象返回,返回呢,付给这个animal,那其实你能看到通过这个new的对象来看,这是不是就是个多态性啊。对,那这时候呢,让这个animal去吃东西,那这时候你说他是吃草呢,还是这个这个吃骨头呢,还是吃鱼呢,你现在拿这个代码看,你能看出来吗。对,你是肯定看不出来的,你要能看出来,那就说它是个变异行为,你现在是确定不了的,因为我们这个随机数呢,你根本不知道是几,哎,它其实就是一个运行时行为,你看我们这时候一执行,我真正去运行了,我这负责学习数是一啊,那这就是给你扭了个狗。然后然后这时候吃呢,就是狗吃骨头了,那再执行,那可能就别的啊,还还是骨头啊。
05:07
哎,这是鱼,这是这个这个猫变成零了,对,就吃鱼,所以呢,我们只有运行的时候呢,才知道你真正拗的是谁,然后呢,我们才能够进而呢,去调你这个子类的那个方法了,所以说呢,我们这个多态性,它是一个运行式行为。啊,接着的话呢,再翻回来,再看咱们刚才说的这个事儿。说呢,这个父类的父类根据呢,赋给它的不同的子类对象,动态的去调用属于子类一个方法,这种方法呢,在编译其是确定不了的。这就说我们多态性的是一个运行时的一个行为啊,然后呢,把整个这个虚拟方法调用的这个过程啊,也可以称作叫动态绑定啊,动态绑定就相当于你这个虚方法呢,是不是绑定了一个子类对象的那个重写的方法了啊,就叫动态绑定,哎,编译时候呢是父类类型,当然运行的时候呢,又是子类的,这个就叫一个动态绑定了,嗯,下边呢,我这还放了一个图。
06:05
哎,放了个图,就是我这呢声明了一个副类叫person类型,下边呢有具体的中国人,韩国人,泰国人,美国人。这个这个这个在person类当中呢,我们定义这个叫welcome欢迎的一个方法了,然后每个子类呢,都重写了,都重写了,重写以后,呃,我们声明的是一个person,但是我们真正new的时候呢,是new的一个子类的对象,那么当你真正是通过这个声明,比如说这个引用叫P,我通过这个P呢去调这个welcome的时候。哎,这个时候呢,调的时候呢,真正他去说欢迎这个事儿了,那就跟你具体这个子类有关系了。啊,你看他是中国人,他就说叫欢迎光临,韩国人呢,这个叫。啊啊,氧化石油是吧,啊,泰国泰国这个这完全不知道啊,日日语是不是还知道日叫什么什么是吧的啊然后这是这个这个美国这都认吧,对,就是说你真正执行的时候呢,是你这个子类这个哎冲洗的一个方法,嗯,萨拉诶这是萨拉迪卡吧,可能是啊嗯,对,就是我们相当于呢,就是再把这个虚拟方法调用,这个事呢,再给大家去强调一下啊,强调一下,明确一下这个问题啊,然后后边这个大家看这个呢,也比较重要一些,就是有一个经典的面试题呢,我们说了叫方法的重载跟重写了。
07:41
啊,那说它俩的话呢,大家就把各自什么是重载,重载的细节是什么,什么是重写,重写呢?诶有哪些具体的权限修饰符啊,反问之类型啊,这块具体要求是什么?哎,你可以说一说,然后除了这个之外。啊,这我第一个就相当于刚才说的这个事儿忽略了,除了之外呢,我们再来看一下重杂和重写。
08:02
说重载这个咱们就整个走一下大家就行啊,说重载呢,是允许这个存在多个同名的方法,而这些方法的参数不一样,说编译器呢,根据这个方法不同的参数列表啊,对同名的方法呢,名称做一个修饰,就做一个区分,说对于编译器来讲,这些同名的方法呢,就成了不同的方法。就是方法名一样,但是参数列表不一样,这也认为是不同的方法,这个它们的调用地址呢,在编译期呢就确定了。就是我们调的是哪个方法,编译期就确定了,说Java的重载是可以包括父类和子类的,就是父类呢,你定义了一个方法,比如叫it没参数,子类呢,调了个it有参数,这两呢仍然叫重载。啊说此类呢,可以重载父类中同名不同参数的这个方法。所以对于重载来讲,主要是由于它在这个编译期间呢,就绑定好了啊,所以对于重载而且来讲,在方法调用之前,我们这个编译期呢,就已经确定了它到底调的是哪个方法,呃,我们把这种呢称作叫早绑定,或者叫静态绑定,就已经绑定好了,那么对于多肽来讲呢,我们只有等到方法调用的那一刻,我们的编译,呃,编译器这时候呢,其实这时候就涉及不到这个编译器是什么啊,具体解释运行的时候啊,解释运行器,它才知道它具体调用的是什么方法了,我们这时候呢,就称为叫玩绑定或者叫动态绑定。
09:28
就一个呢是编译期才确定的,一个呢是到运行期才确定的,这个其实跟编译器没有太大关系哈,这是我们解释运行器。啊,或者这时候你泛泛的就称为编译器,呃,也能马马虎虎,但实际上呢,这时编译器没关系了,编译器不知道运行的时候呢,这个都是解释运行器来操作的哈,他这时候才知道具体用的是哪个方法,我们就称作叫动态绑定。啊,那么引用这个叫Bruce eo他的话,这个是谁啊?
10:01
这个就是大家,你那本章法变成思想的作者啊,这是个大神了,这个C加加变成思想也是他写的啊,这哥们很牛的啊,就是他呢说过一句话说不要犯傻,如果他不是完绑定,他就不是多肽啊,所以呢,我们把这个诶相当于呢,是不是重写可以理解成是多肽了。因为它属于这种动态绑定晚绑定的,呃,而我们这个呃重载的话呢,他在编译期呢,其实就已经确定了,所以重载的话,我们就不认为它是一个呃多肽了。哎,就这样的点啊行这块的话呢,大家下来呢,再去理解理解这里边说的这个内容啊。
我来说两句