小伙伴们大家好我是阿澜今天依旧带来韩顺平笔记需要的小伙伴可以看看。如果有一起学Java的可以留个印一起打卡我每天会发布当天的笔记和一些感悟~~今日课程内容韩顺平Java课程309~~316目录一多态的向上转型1.能使用哪些方法和属性是由编译类型决定的2.最终的运行效果是看子类的具体实现二多态的向下转型三属性没有重写一说四instanceof操作符的类型问题五易错题六动态绑定机制七多态数组一多态的向上转型定义父类的引用指向了子类的对象。1.能使用哪些方法和属性是由编译类型决定的比如下面首先我们假定新创建一个Animal的子类叫做Cat在Cat里新写一个catch Mouse方法抓老鼠。父类Animal里没有的哦接着创建一个animal对象他的运行类型是Cat我们想在main方法里调用catchmouse方法就会写出animal.catchMouse别忘了括号但是此时会编译器报错。为什么呢因为在编译阶段能使用哪些方法和属性是由编译类型决定的 编译器在编译的时候是按照Animal类型编译的而Animal类型没有catchmouse这个方法哪怕实际上animal对象的实际类型是Cat类型但是编译器不知道的他只认为animal是Animal类型而Animal类型没有的你在调用方法的时候就不能用。如果你用了那么你就会编译报错ps:Animal animal new Cat()左边的类型是编译类型右边是运行类型。2.最终的运行效果是看子类的具体实现刚刚的编译阶段已经告一段落来到了代码实际运行的阶段。编译成功后代码运行的时候实际上是以Cat类来对待的优先从Cat里找成员。这与前面并不矛盾因为1.1讲的是编译阶段也就是javac阶段编译好后运行的时候就要看运行类型了即Java阶段。即调用时从子类类型运行类型开始找方法运行。二多态的向下转型如果我们想使用子类特有的方法该怎么办呢这就要用到向下转型了这里关于第二点要强调一下这里只是转变了父类的引用类型但是创建的这个对象的类型并没有改变。这个对象创好后的类型就不变了你所能改变的不过是引用类型罢了。例相当于原来有一个Animal类型的变量名animal指向了内存中开辟的一块Cat对象而现在又创建了一个Cat类型的变量名cat指向同一块Cat对象。只不过编译的时候有区别罢了。就像一个人小时候叫小明长大后改名了叫二狗。虽然名字变了但是指向的人是一样的。答案不行因为animal的运行类型是Cat要向下转换也只能是转向Cat而不是Dog。三属性没有重写一说和之前的方法不同属性的值是由编译类型觉定的这里开辟了一个子类的sub对象并且进行了向上转型在内存里sub对象有两个属性一个是父类的count10一个是子类的count20在main方法中如果要输出base。count的值的话如果按照方法的运行规则从子类开始访问的话就应该是count20.。但是输出的是10因为属性的值是由编译类型决定的。四instanceof操作符的类型问题那么在判断的时候是按照编译类型还是运行类型来判断的呢先说答案运行类型。如果 前面的运行类型是后面的类型或其子类那么返回true。ps:此操作符只适1用于有关系的父子类之间的比较如果两个毫无关系的类型进行比较会报错。五易错题1.2.这里关于bs的输出有个强调这就是前面说的只改名字不改类型b和s指向的是同一个空间所以返回true。六动态绑定机制例题以a.sum为例因为子类中没有sum方法所以要从父类A中调用sum方法而sum方法需要调用getI方法那么问题来了父类和子类都有getI方法用哪个呢这就要用到动态绑定机制了即调用对象方法的时候需要与对象的运行方法绑定也就是说a的运行方法也就是子类了。然后开始调用子类的getI方法而用这个方法又要用属性i这个时候就不用往出跳了在哪个类就用谁的方法。一句话总结动态绑定只看有没有重写方法如果写了就用新的方法没写就用父类的方法。用方法的时候就看运行类型属性没要求在哪个类里要用就在哪个类里看。七多态数组定义数组的定义类型为父类类型而里面存放的实际上是子类类型。这里有个注意点因为数组的元素可能是不同的子类那么在调运方法时要切记动态绑定机制这里使用元素的编译类型是父类类型而运行类型要看自己的定义