【Java多态&转型 10】
一、转型
1、向上转型:父类-->子类,自动类型转换
向下转型:子类-->父类,强制类型转换,在前面加(数据类型)
2、转型必须是有继承关系,否则不能进行转型
3、转型的两个阶段:
编译阶段:静态加载 (引用部分就是编译阶段)
运行阶段:动态加载 (创建对象就是运行阶段)
例如:Animal a1 = new Cat(); Animal a1是编译阶段,new Cat()是运行阶段 这种情况就叫”多态“
4、向上转型,只要编译没问题,运行都能通过
向下转型,编译没有问题,也有可能会报:java.lang.ClassCastException异常
原因: 父类的引用指向了其中一个子类的对象,此引用又强制转换成没有指向的子类类型,就会报异常
解决方案:采用instanceof运算符,此运算符是一个boolean类型
语法:(引用 instanceof 类型)
例如:(a instanceof Cat)
如果结果是true,表示a引用指向的堆中的java对象是Cat类型
如果结果不是true,表示a引用指向的堆中的java对象不是Cat类型
package com.JavaStudy.study0429; /** 方法覆盖 */ public class Animal { public void move(){ System.out.println("动物在移动!"); } }
package com.JavaStudy.study0429; public class BackCat extends Cat{ public void move(){ System.out.println("黑猫警长在移动!"); } }
package com.JavaStudy.study0429; public class Cat extends Animal { @Override //注解,作用是校验是否满足当前的语言 public void move(){//方法覆盖发生在继承类内,并且方法名,类型都相同 System.out.println("猫在移动!"); } public void fly(){ System.out.println("猫不会飞!"); } }
package com.JavaStudy.study0429; public class Test1 { public static void main(String[] args){ Animal a1 = new Cat(); a1.move();//自动类型转型(向上转型) Cat a2 = (Cat)a1;//强制类型转型(向下转型) a2.fly(); BackCat a3 = (BackCat) a1;//指向Cat的引用,强制转型为BackCat的引用,会报java.lang.ClassCastException异常 if(a1 instanceof Cat){//java中规范要求在做任何强制类型转换之前都需要用instanceof运算符 BackCat a4 = (BackCat) a1; }//判断a1指向Cat类型,执行结果为false,所以会报异常 if(a1 instanceof BackCat){ BackCat a5 = (BackCat)a1; }//判断a1指向BackCat对象,执行结果为true,所以不会报异常 } }
例2:
package com.JavaStudy.study0508; /** * @Author wufq * @Date 2020/5/8 16:19 */ public class Animal { public void eat(){ System.out.println("Animal eat!"); } }
package com.JavaStudy.study0508; /** * @Author wufq * @Date 2020/5/8 16:19 */ public class Bird extends Animal{ public void eat(){ System.out.println("Bird eat!!!"); } }
package com.JavaStudy.study0508; /** * @Author wufq * @Date 2020/5/8 16:19 */ public class Cat extends Animal{ public void eat(){ System.out.println("Cat eat!"); } }
package com.JavaStudy.study0508; /** * @Author wufq * @Date 2020/5/8 16:19 */ public class Dog extends Animal{ public void eat(){ System.out.println("Dog eat"); } }
package com.JavaStudy.study0508; /** * @Author wufq * @Date 2020/5/8 16:19 */ public class Fish extends Animal{ public void eat(){ System.out.println("Fish eat"); } }
package com.JavaStudy.study0508; /** * @Author wufq * @Date 2020/5/8 16:19 */ public class Person { // public void feed(Bird b){ // b.eat(); // } // // public void feed(Cat c){ // c.eat(); // } // // public void feed(Dog d){ // d.eat(); // } // // public void feed(Fish f){ // f.eat(); // } /* 多态的一个好处:降低耦合性,提高扩展性 */ public void feed(Animal a){ //父类的对象引用 a.eat(); } }
package com.JavaStudy.study0508; /** * @Author wufq * @Date 2020/5/8 16:20 */ public class Test { public static void main(String[] args){ //创建宠物 Bird b = new Bird(); Cat c = new Cat(); Dog d = new Dog(); Fish f = new Fish(); //创建主人 Person p = new Person(); //喂养 p.feed(b);//传入子类的对象引用,这样在执行的时候,就发生了多态(Animal a = new Bird();) p.feed(c); p.feed(d); p.feed(f); } }
二、运用多态说明私有方法和静态方法不能覆盖
私有方法
package com.JavaStudy.study0508New; /** * @Author wufq * @Date 2020/5/8 17:46 */ public class A { //私有方法 private void m1(){ System.out.println("A 中的m1方法被调用!"); } public static void main(String[] args){ A a = new B(); a.m1(); } } class B extends A{ public void m1(){ System.out.println("B 中的m1方法被调用!"); } } /* 假设私有方法可以进行覆盖,那么多态调用m1方法后,应该打印:B 中的m1方法被调用! 实际打印:A 中的m1方法被调用! 说明:私有方法不能被覆盖 */
静态方法