java的向上转型和向下转型

目录

 

一、 首先介绍instanceof关键字

 二、向上转型

三、 向下转型


 

一、 首先介绍instanceof关键字

格式:对象 instanceof 类名称

作用:判断对象是否是特定类的一个实例,是返回true,否则返回false.

  •  举个栗子:
package zl;

public interface Person {
    public void eat();
}
package zl;

public class People implements Person {

     @Override
     public void eat() {
          System.out.println("people eat...");
     }
}
package zl;
public class xiaoming extends People {

    @Override
    public void eat() {
         System.out.println("xiaoming eats...");
    }
}
package zl;

public static void main(String[] args) {
      People p=new People();
      xiaoming x=new xiaoming();
      System.out.println(p instanceof Person);//true
      System.out.println(p instanceof xiaoming);//false
      System.out.println(x instanceof Person);//true
      System.out.println(x instanceof People);//true
 }

 结果解释:

Person是接口,People类继承接口Person,xiaoming类继承People类。

从上述结果可以总结:

对象instanceof接口,都为true;

对象instanceof父类,都为true;

对象instanceof他的子类为false。

  • 再举个栗子:
package zl;

interface A{    
    
}    
class B implements A{    
         
}    
class C extends B{    
         
}    
public class Iinstanceof {    
    
    public static void main(String[] args) {    
        A ab=new B();    
        A ac=new C();    
        B bc=new C();    
        B bb=new B();    
        C cc=new C();    
        //对象实现一个接口,用这个对象和这个接口进行instanceof判断,都为true。    
        System.out.println("ab instanceof A="+(ab instanceof A));    
        System.out.println("ac instanceof A="+(ac instanceof A));    
        System.out.println("bc instanceof A="+(bc instanceof A));    
        System.out.println("bb instanceof A="+(bb instanceof A));    
        System.out.println("cc instanceof A="+(cc instanceof A));    
        //对象和父类进行instanceof判断,都为true    
        System.out.println("ab instanceof B="+(ab instanceof B)); //true   
        System.out.println("ac instanceof B="+(ac instanceof B));    
        System.out.println("bc instanceof B="+(bc instanceof B));    
        System.out.println("bb instanceof B="+(bb instanceof B));    
        System.out.println("cc instanceof B="+(cc instanceof B));    
        //对象和他的子类进行instanceof判断为false    
        System.out.println("ab instanceof C="+(ab instanceof C));    
        System.out.println("ac instanceof C="+(ac instanceof C)); //true   
        System.out.println("bc instanceof C="+(bc instanceof C)); //true   
        System.out.println("bb instanceof C="+(bb instanceof C));    
        System.out.println("cc instanceof C="+(cc instanceof C));    
    }    
}    

运行结果:

 结果解释:

此例与上例不同之处在于注释行,进行了向上转型,综上,可总结为:

对象instanceof接口,都为true;

对象instanceof父类,都为true;

对象instanceof他的子类为false;

对象)instanceof(他的向上转型使用的子类),为true。

 二、向上转型

将子类对象转为父类对象,此处父类对象可以是接口(父<--子)

  • 举个栗子:
package zl;

public abstract class Animal {
    public abstract void eat();
}
package zl;

public class Cat extends Animal {

    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }
    public void catchMouse(){
        System.out.println("Just for fun !");
    }
}
package zl;

public class Dog extends Animal {
    @Override
    public void eat() {
        System.out.println("吃肉");
    }
    public void lookHome(){
        System.out.println("二哈看家");
    }
}
package zl;

public class demo_instanceof {

    public static void main(String[] args) {
        Animal animal = new Cat();        //向上转型
        animal.eat();                     //调用cat.eat()
        //animal.catchMouse(); 出现红波浪线错误

        if (animal instanceof Dog) {
            Dog dog = (Dog) animal;       
            dog.lookHome();
        }
        if (animal instanceof Cat) {      //向上转型后的父类对象还是子类的一个实例
            Cat cat = (Cat) animal;       //向下转型
            cat.catchMouse();
        }

        giveMeAnAnimal(new Cat());
        giveMeAnAnimal(new Dog());
    }

    private static void giveMeAnAnimal(Animal animal) {    //向上转型
        if (animal instanceof Dog) {
            Dog dog = (Dog) animal;    //向下转型
            dog.lookHome();
        }
        if (animal instanceof Cat) {
            Cat cat = (Cat) animal;//向下转型
            cat.catchMouse();
        }
    }
}

运行结果: 

 结果解释:

Animal animal = new Cat();向上转型时animal会遗失除与子类对象共有的其他方法,此处遗失catchMouse();调用与子类对象共有的方法时将调用子类的方法,即调用animal.eat(); 相当于调用cat.eat()。

animal instanceof Cat(Animal的向上转型使用的子类) 结果为true;animal instanceof Dog(Animal的子类) 结果为false;

向上转型的好处 :

giveMeAnAnimal(Animal animal)方法以父类为参数,调用时用子类作为参数 giveMeAnAnimal(new Cat()); giveMeAnAnimal(new Dog());利用了向上转型。此时需使用instanceof判断要执行的代码块。

如果giveMeAnAnimal以子类对象为参数,则有多少个子类就需要写多少个函数。这也体现了JAVA的抽象编程思想。

三、 向下转型

把父类对象转为子类对象

package zl;

public class Girl {  
    public void smile(){  
        System.out.println("girl smile()...");  
    }  
}  
package zl;

public class MMGirl extends Girl{     
    @Override  
    public void smile() {          
        System.out.println("MMGirl smile sounds sweet...");  
    }  
    public void c(){  
        System.out.println("MMGirl c()...");  
    }  
}  
package zl;

class Main{  
    
    public static void main(String[] args) {  
          
        Girl g1=new MMGirl(); //向上转型   
        g1.smile();  //MMGirl.smile()
          
        MMGirl mmg=(MMGirl)g1; //向下转型,编译和运行皆不会出错  
        mmg.smile();  
        mmg.c(); //要调用非公共方法时,必须 向下转型
          
          
        Girl g2=new Girl();  
//        MMGirl mmg1=(MMGirl)g2; //不安全的向下转型,编译无错但运行会出错 java.lang.ClassCastException
//        mmg1.smile();  
//        mmg1.c();  

        //替换掉上述注释的代码
        if(g2 instanceof MMGirl){ //避免 不安全的向下转型(即没有经过向上转型不可以进行向下转型)
            MMGirl mmg1=(MMGirl)g2;   
            mmg1.smile();  
            mmg1.c();  
        }  
          
    }  
}  

运行结果: 

结果解释:

c()方法只有MMGirl类有,Girl类中无,要想调用c()方法,必须进行向下转型,此处为MMGirl mmg=(MMGirl)g1;

直接向下转型Girl g2=new Girl();  MMGirl mmg1=(MMGirl)g2;不安全,通过判断g2 instanceof MMGirl可避免出现java.lang.ClassCastException错误。

 向下转型的好处

由上述例子可总结为:1.通过向下转型调用子类中父类没有的方法;2.使用向下转型时一定要使用instanceof 判断。

 参考链接:https://www.cnblogs.com/ggzhangxiaochao/p/9528656.htmlhttps://blog.csdn.net/liuchaoxuan/article/details/79937538https://blog.csdn.net/chenz_yang/article/details/75137973https://blog.csdn.net/mingxu_W/article/details/86362031

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值