一、转型
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类型
packagecom.JavaStudy.study0429;/**方法覆盖*/
public classAnimal {public voidmove(){
System.out.println("动物在移动!");
}
}
packagecom.JavaStudy.study0429;public class BackCat extendsCat{public voidmove(){
System.out.println("黑猫警长在移动!");
}
}
packagecom.JavaStudy.study0429;public class Cat extendsAnimal {
@Override//注解,作用是校验是否满足当前的语言
public void move(){//方法覆盖发生在继承类内,并且方法名,类型都相同
System.out.println("猫在移动!");
}public voidfly(){
System.out.println("猫不会飞!");
}
}
packagecom.JavaStudy.study0429;public classTest1 {public static voidmain(String[] args){
Animal a1= newCat();
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 instanceofBackCat){
BackCat a5=(BackCat)a1;
}//判断a1指向BackCat对象,执行结果为true,所以不会报异常
}
}
例2:
packagecom.JavaStudy.study0508;/*** @Author wufq
* @Date 2020/5/8 16:19*/
public classAnimal {public voideat(){
System.out.println("Animal eat!");
}
}
packagecom.JavaStudy.study0508;/*** @Author wufq
* @Date 2020/5/8 16:19*/
public class Bird extendsAnimal{public voideat(){
System.out.println("Bird eat!!!");
}
}
packagecom.JavaStudy.study0508;/*** @Author wufq
* @Date 2020/5/8 16:19*/
public class Cat extendsAnimal{public voideat(){
System.out.println("Cat eat!");
}
}
packagecom.JavaStudy.study0508;/*** @Author wufq
* @Date 2020/5/8 16:19*/
public class Dog extendsAnimal{public voideat(){
System.out.println("Dog eat");
}
}
packagecom.JavaStudy.study0508;/*** @Author wufq
* @Date 2020/5/8 16:19*/
public class Fish extendsAnimal{public voideat(){
System.out.println("Fish eat");
}
}
packagecom.JavaStudy.study0508;/*** @Author wufq
* @Date 2020/5/8 16:19*/
public classPerson {//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();
}
}
packagecom.JavaStudy.study0508;/*** @Author wufq
* @Date 2020/5/8 16:20*/
public classTest {public static voidmain(String[] args){//创建宠物
Bird b = newBird();
Cat c= newCat();
Dog d= newDog();
Fish f= newFish();//创建主人
Person p = newPerson();//喂养
p.feed(b);//传入子类的对象引用,这样在执行的时候,就发生了多态(Animal a = new Bird();)
p.feed(c);
p.feed(d);
p.feed(f);
}
}
二、运用多态说明私有方法和静态方法不能覆盖
私有方法
packagecom.JavaStudy.study0508New;/*** @Author wufq
* @Date 2020/5/8 17:46*/
public classA {//私有方法
private voidm1(){
System.out.println("A 中的m1方法被调用!");
}public static voidmain(String[] args){
A a= newB();
a.m1();
}
}class B extendsA{public voidm1(){
System.out.println("B 中的m1方法被调用!");
}
}/*假设私有方法可以进行覆盖,那么多态调用m1方法后,应该打印:B 中的m1方法被调用!
实际打印:A 中的m1方法被调用!
说明:私有方法不能被覆盖*/
静态方法