00:00
我们来看一下这个多态性课后的这个练习题,这呢有好几个分别呢,来看一下,首先第一个问题,这个问题的话呢,我们把它粘出来放到咱们这个。工程项起来看一下,我新建一个包,放一下这个练习EX12这里呢,我们把这个类叫成叫field method test。CTRLV一下分类是这呢,我把这样的几个类呢都分别的粘过来看这道题里边它的考察的一些知识点,这呢其实你可以看成是一道笔试题,Shift f以下这道题呢,还是有一点难度的,看一下base当中定义了一个count display方法输出一下我们这个count值没了子类,子类呢里边也定义一个同名的属性。
01:00
20这呢display对上面这个方法进行了一个重写,我们说过在属性方面不体现为多态性,这个你要记住方法这块呢体现接下来我呢new了一个sub,付给的也是一个sub。要小心点,然后呢,这时候我们去s.count问这时候是多少。靠多少这个时候呢,应该得会,就这个时候呢,其实它还难度还OK啊,这个是20,这个你可能会去想多态性,这就别想多态性也没跟多带性也没啥关系啊,我们这时候呢,你调抗的首先明确一点呢,有同学说十的,有说20的,至少你能清楚一点,内存中确实十二十都有。都有,那到底是谁呢?那就看你声明的是谁,我声明的是一个sub,那你这块呢,它掉的它就是你这个子类中的这个。
02:02
或者说咱们当时讲那个,呃,讲完super讲super的时候呢,咱不是也说过这个事儿,有super有这次比如说super呢,你你调个属性,这次调个属性,咱们这个这次掉的这个属性是不是也不一定就非得是你自己类定义的,也可能是负类中的一个属性啊。咱们这个这次掉的这个属性,它也可能是负类的啊,只是说呢,咱们是先在自己这个类中去找,没找到了,我再去负类中去找,你要在子类中找到了,那就用你自己这个了,那也就说明他其实还是有这种就近原则的,我们这里边你这个sub也是一样,他就近的话呢,也是先去他自己类里找,我是不是找到了,找到了那就是20,我就不再去这个负类中找了,你要说我这个叫COUNT1,我这个叫COUNT2,然后我这个位置我写COUNT1,对,那肯定是十了,因为你先去自己这找是没找到啊,那去负类找,找着了,找着那就是十,但现在的话呢,两重名了,重名呢就是先去你自己找,找着了,找着就不用再去找那个十了,所以这呢是20没有问题,下边。
03:09
s.display多少,这个说实也不合适了,这个呢,你想我这个display我是不是重写了,就是你这个要认可20了,这个呢,你就没有道理再去写十了。因为我这呢调的是这个方法,那你自然而然这次点是不是一定是20了,对,所以呢,我们先验证一下咱们现有的这个情况。OK,没问题。这个得会通过这些题的话呢,我们去熟悉一下他这个到底执行的一个情况,大家以后你要写代码出现这样问题了,你得知道是为什么,接下来我这是一个多肽,我把一个子类的对象呢,赋给了一个负类的引用,赋完以后首先问一下B是否等等于小S。
04:00
等等于咱们没有说系统的总结,咱们讲完这个多的这个练习以后呢,我们说object,说object的时候呢,我们需要呢,这个讲EQ的方法,那顺便呢,我们把这个等等呢给大家总结一下,此时的等等它应用在引用数据类型上了。对于引用数据类型这个等等,它比较的是地址值,此时呢,我们这个等等,对于引用数据类型来讲。比较的是两个引用数据类型变量的地址值是否相同?地址相同吗?类型它有类型的类型,类型它这个类型呢,一定是可以统一的了,要不统一呢,他回头就报错了,这个我们后边说啊,你就先先你主要判断地址,这个就是看地址,就是你要是类型都不一样,这个编译就过不了,这编译能过,它这个类型是可以统一在一起的。
05:09
那这时候呢,你说地址值它俩一样吗?肯定一样啊,你S负值,咱们讲负值负值负的不就是地址值吗?负过来还不一样,那没天理了。所以这呢一定是出。这是处,他俩呢,就是指向的同一个对空间中的对象,那么我通过B去调count,这是多少?B掉COUNT10还是二十十,这个咱们不是说多态性不适用于这个属性吗?对,就是你这个靠的是谁,你就看左边声明什么类型边异运行都看左边B这不是个多态星吗?多态性有了以后呢,我们这个属性呢,这不都看左边吗?十倍哎,我把这个注释掉到这呢,就已经是有难度了,是那如果这道题呢,写到这程度呢?其实还差点意思,我就没有必要给大家出这道题了。最有意思的是我最后还加了一个叫display b.display你说执行的是这个还是执行的下一个哪个呀?下一个吗?
06:31
刚讲完多肽性,你要说是上一个那多肽白讲了,生面那个多肽,我们通过这个引用调你这个子非这种都有这个方法的时候,实际执行的说了不是说子类吗?这不就虚拟方法调用吗?那既然呢,你执行的是这个方法了,那结果是多少,那就是20,所以说呢,你看以为呢,多态性理解的挺透彻的,结果实际上一写题发现诶还是差点意思,就是严格按照咱们说的这个知识点去往下捋,它就不会出问题。
07:03
所以这个题呢,出完以后呢,它有一个比较有意思的点,比较有意思的点什么点呢?大家看这个换一个颜色,我这个造了一个对象,把这个对象呢付给另外一个声明了,实际上是一个多态的形式,这两个引用的地址呢也完全一样,就意味着呢,你两个指向呢,是堆空间中的同一个对象,实体指向的是同个东西,结果呢,你却发现我们用不同的变量去调的时候呢,诶这俩哥们呢,出来的结果还不一样。哎,就是这样一个有意思的点,这呢,仅仅做一道考题出现就行,在咱们实际开发当中,大家定义类的时候,尤其是这种子负类的时候,不要出现子父类当中同名的属性,因为呢,一旦出现以后你就懵了,只要这里边这个叫COUNT1,这个叫COUNT2,不会有任何问题,你肯定都清楚,关键就是俩同名的时候呢,你就懵了,所以咱们开发中大家不要去定义同名的属性方法,你定义同名同同这个参数了,那是你要重写了,那肯定会出现的,好注意这个情况,通过这个呢,我们想总结的这个知识点呢,我就写到这个下边了,CTRLC。
08:15
这是咱们这个练习,然后粘过来。看一下说若子类重写了父类方法,就意味着呢,子类里定义的方法呢,彻底呢覆盖了父类里边的同一方法系统呢,将不再可能把父类中的方法呢转移到子类当中,就意味着呢,我们通过这个b.display执行的就是重写的方法,下一个。这是第一个想说明的点。第二个对于实例变量则不存在这样的现象,即使此类里定义了与负类中相同的实例变量,这个实例变量呢,依然不可能覆盖负类中定义的实例变量,那就意味着在堆空间当中,我们实际上存在两个count属性不覆盖,那么到底调的是谁,就看你声明的是谁,声明谁就调谁。
09:12
就这样,所以呢这呢体现为叫编译运行都看左边啊,那这呢,就是我们所说的边一看左边,运行看右边。好,这呢就是我们这道题呢,想强调的一个知识点。
我来说两句