精华内容
下载资源
问答
  • java向下转型

    千次阅读 2019-06-08 23:03:21
    在对象向下转型中,父类实例是不可能强制转换成任意子类实例,必须先通过子类实例化,利用向上转型让父类对象与具体子类实例发生联系后才可以向下转型,否则将出现ClassCastException异常 ...

    在对象向下转型中,父类实例是不可能强制转换成任意子类实例,必须先通过子类实例化,利用向上转型让父类对象与具体子类实例发生联系后才可以向下转型,否则将出现ClassCastException异常

    展开全文
  • Java向下转型

    千次阅读 2018-02-06 17:23:47
    情况二:如果父类引用的对象是父类实例,那么在向下转型的过程中是不安全的,编译不会出错,但是运行时会出现java.lang.ClassCastException错误。class Father{}class Son extends Father{ public s

    在向下转型过程中,分为两种情况:

    情况一:如果父类引用的对象是指向的子类实例,那么在向下转型的过程中是安全的。也就是编译是不会出错误的。

    情况二:如果父类引用的对象是父类实例,那么在向下转型的过程中是不安全的,编译不会出错,但是运行时会出现java.lang.ClassCastException错误。

    class Father{}
    
    class Son extends Father{
        public static void main(String args[]){
            Father f1=new Son();
            Son s1=(Son)f1;//安全的向下转型,编译和运行皆不会出错
            //Father f2=new Father();
            //Son s2=(Son)f2;//不安全的向下转型,编译无错但运行会出错
            }
    }
    

    向下转型的意义
    很多时候,我们需要把很多种类的子类实例对象全部扔到存放父类实例的集合。

    经过了这个过程,子类实例已经赋值给了父类引用(即完成了向上转型),但很遗憾的丢失了子类扩展的方法。

    很好的是Java语言有个向下转型的特性,让我们可以重新获得丢失的方法,即强转回子类

    所以我们需要用到子类实例的时候,就从那个父类集合里拿出来向下转型就可以了,一样可以使用子类实例对象

    Java中的集合在存入元素时,都是Object引用指向元素实例,所以在取出时需要进行强制转换。而泛型集合会自动在取出时进行强制转换。

    而在Android开发中,我们在Layout文件夹,用xml写的控件。为什么能在Activity等组件中通过 findViewById() 方法找到呢?为什么 findViewById(R.id.textview) 方法传入TextView的id后,还要转型为TextView呢?这就是 Java 向下转型的一个应用

    展开全文
  • Java向下转型的意义

    万次阅读 多人点赞 2016-08-17 16:13:01
    一开始学习 Java 时不重视向下转型。一直搞不清楚向下转型的意义和用途,不清楚其实就是不会,那开发的过程肯定也想不到用向下转型。其实向上转型和向下转型都是很重要的,可能我们平时见向上转型多一点,向上转型也...

    一开始学习 Java 时不重视向下转型。一直搞不清楚向下转型的意义和用途,不清楚其实就是不会,那开发的过程肯定也想不到用向下转型。

    其实向上转型和向下转型都是很重要的,可能我们平时见向上转型多一点,向上转型也比较好理解。
    但是向下转型,会不会觉得很傻,我是要用子类实例对象,先是生成子类实例赋值给父类引用,在将父类引用向下强转给子类引用,这不是多此一举吗?我不向上转型也不向下转型,直接用子类实例就行了。
    我开始学习Java时也是这么想的,这误区导致我觉得向下转型就是没用的。
    随着技术的提升,我在看开源的项目学习,发现很多地方都用了向下转型的技术,这就让我重视了起来,想要重新来复习(学习)这个知识点。也是搜索了许多博客文章,但都没具体说明向下转型,只是给了例子演示怎么使用,反而是向上转型讲了一堆(可能是我没找到)。

    这篇博客就是讲向下转型的,那我们就来学习下向下转型,了解下这种特性的意义和使用场景

    新建一个电子产品接口,如下:

    public interface Electronics{
    
    }
    

    很简单,什么方法都没有。

    新建一个Thinkpad笔记本类,并实现电子产品接口:

    public class Thinkpad implements Electronics{
    
        //Thinkpad引导方法
        public void boot(){
            System.out.println("welcome,I am Thinkpad");        
        }
    
        //使用Thinkpad编程  
        public void program(){
            System.out.println("using Thinkpad program");
        }
    
    }
    

    新建一个Mouse鼠标类,并实现电子产品接口:

    public class Mouse implements Electronics{
    
        //鼠标移动
        public void move(){
            System.out.println("move the mouse");       
        }
    
        //鼠标点击  
        public void onClick(){
            System.out.println("a click of the mouse");
        }
    
    }

    新建一个Keyboard键盘类,并实现电子产品接口:

    public class Keyboard implements Electronics{
    
        //使用键盘输入    
        public void input(){
            System.out.println("using Keyboard input");
        }
    
    }

    这里子类比较多,是为了更好的理解。每个类的方法的逻辑实现也很简单。打印了一行信息

    接下来,我们想象一个情景:我们去商城买电子产品,电子产品很多吧,比如笔记本电脑,鼠标,键盘,步步高点读机哪里不会点哪里,我们用的手机,等等,这些都属于电子产品。电子产品是抽象的。好,那么我们决定买一台Thinkpad,一个鼠标和一个键盘。
    这时,我们需要一个购物车来装这些电子产品吧。我们可以添加进购物车,然后通过购物车还能知道存放的电子产品数量,能拿到对应的电子产品。
    那么,一个购物车类就出来了,如下:

    import java.util.ArrayList;
    import java.util.List;
    
    public class ShopCar{
    
        private List<Electronics> mlist = new ArrayList<Electronics>();
    
        public void add(Electronics electronics){
    
            mlist.add(electronics);
    
        }
    
        public int getSize(){
    
            return mlist.size();
        }
    
    
        public Electronics getListItem(int position){
    
            return mlist.get(position);
    
        }
    
    
    }
    

    List 集合是用来存放电子产品的,add 方法用来添加电子产品到购物车,getSize 方法用来获取存放的电子产品数量,getListItem 方法用来获取相应的电子产品。

    可以看到 List<Electronics> 用了泛型的知识,至于为什么要用泛型?这个不做介绍了,泛型很重要的。
    而我觉得比较疑惑的是为什么是放 Electronics 的泛型,而不是放Thinkpad,Mouse,Keyboard,Phone等?
    那么如果是List<Thinkpad>,肯定是放不进鼠标Mouse的吧,难道要生成3个集合?这里是定义了3个电子产品类,但是我如果有100种电子产品呢,要定义100个集合?
    这太可怕了。所以之前,我们写了一个Electronics接口,提供了一个Electronics的标准,然后让每一个Electronics子类都去实现这个接口。

    实际上这里又涉及到了向上转型的知识点,我们虽然在add 方法将子类实例传了进来存放,但子类实例在传进去的过程中也进行了向上转型
    所以,此时购物车里存放的子类实例对象,由于向上转型成Electronics,已经丢失了子类独有的方法,以上述例子来分析,Thinkpad实例就是丢失了boot() 和program() 这两个方法,而Mouse实例就是丢失了move()和onClick()这两个方法

    但是实际使用Thinkpad或Mouse或Keyboard时,这种情况肯定不是我们想要的

    接着我们写一个测试类 Test 去测试购物车里的电子产品。

    测试类 Test 如下:

    public class Test{
    
        public static final int THINKPAD = 0;
        public static final int MOUSE = 1;
        public static final int KEYBOARD = 2;
    
        public static void main(String[] args){
    
            //添加进购物车
            ShopCar shopcar = new ShopCar();
            shopcar.add(new Thinkpad());
            shopcar.add(new Mouse());
            shopcar.add(new Keyboard());
    
            //获取大小
            System.out.println("购物车存放的电子产品数量为 ——> "+shopcar.getSize());
    
    
            //开始测试thinkpad电脑
            Thinkpad thinkpad = (Thinkpad)shopcar.getListItem(THINKPAD);
            thinkpad.boot();
            thinkpad.program();
    
            System.out.println("-------------------");
    
            //开始测试Mouse鼠标
            Mouse mouse = (Mouse)shopcar.getListItem(MOUSE);
            mouse.move();
            mouse.onClick();
    
            System.out.println("-------------------");
    
            //开始测试Keyboard键盘
            Keyboard keyboard = (Keyboard)shopcar.getListItem(KEYBOARD);
            keyboard.input();
        }
    
    }

    运行截图:


    这里写图片描述
    举个例子分析就好

    //开始测试thinkpad电脑
    Thinkpad thinkpad = (Thinkpad)shopcar.getListItem(THINKPAD);
    thinkpad.boot();
    thinkpad.program();
    

    shopcar.getListItem(THINKPAD)这句代码是获取到Electronics类型的实例。不是Thinkpad的实例

    通过向下转型,赋值给子类引用

    Thinkpad thinkpad = (Thinkpad)shopcar.getListItem(THINKPAD);

    这样子类实例又重新获得了因为向上转型而丢失的方法(boot 和program)

    总结一下吧,很多时候,我们需要把很多种类的实例对象,全部扔到一个集合。(这句话很重要)
    在这个例子里就是把Thinkpad笔记本,Mouse鼠标,KeyBoard键盘等实例对象,全部扔到一个Shopcar购物车集合。
    但是肯定不可能给他们每个种类都用一个独立的集合去存放吧,这个时候我们应该寻找到一个标准,接口就是一个标准。这些都是各种电子产品,抽象成电子产品。然后一个Electronics接口就出来了。
    在回到刚才,我们把很多种类的实例对象全部扔到一个集合。或许这样比较好理解:把很多种类的子类实例对象全部扔到存放父类实例的集合。
    经过了这个过程,子类实例已经赋值给了父类引用(即完成了向上转型),但很遗憾的丢失了子类扩展的方法。
    很好的是Java语言有个向下转型的特性,让我们可以重新获得丢失的方法,即强转回子类
    所以我们需要用到子类实例的时候,就从那个父类集合里拿出来向下转型就可以了,一样可以使用子类实例对象

    ……

    我在搜索java向下转型的意义时,得到一个比较好的答案是这样的:
    最大的用处是java的泛型编程,用处很大,Java的集合类都是这样的。

    而在Android开发中,我们在Layout文件夹,用xml写的控件。为什么能在Activity等组件中通过 findViewById() 方法找到呢?为什么 findViewById(R.id.textview) 方法传入TextView的id后,还要转型为TextView呢?这就是 Java 向下转型的一个应用

    展开全文
  • java 向下转型与instanceof关键字-总结 文章目录java 向下转型与instanceof关键字-总结1. 向下转型和instanceof关系1.1. 为什么要有向下转型1.2. 向下转型和instanceof有什么关系2. 向下转型和instanceof示例Demo2.1...

    java 向下转型与instanceof关键字-总结

    1. 向下转型和instanceof关系

    1.1. 为什么要有向下转型

    向下转型出现的原因:有了对象的多态性以后,内存中实际上是加载了子类特有的属性和方法的,但是由于变量声明为父类类型,导致编译时,只能调用父类中声明的属性和方法。子类特有的属性和方法不能调用。
    如何才能调用子类特有的属性和方法:向下转型:使用强制类型转换。

    		//Person是父类;Man是子类;Woman是子类;
    		//对象的多态性:父类的引用指向子类的对象
            Person per = new Man();
            //强制将Person类型装换为Man类型
            Man man = (Man) per;
            man.setManId(111);
            System.out.println("使用向下转型调用子类特有的属性和方法");
    

    1.2. 向下转型和instanceof有什么关系

    使用强转时,可能出现ClassCastException的异常。
    为了避免在向下转型时出现ClassCastException的异常,我们在向下转型之前,先进行instanceof的判断,一旦返回true,就进行向下转型。如果返回false,不进行向下转型。

    		//使用强转时,出现 java.lang.ClassCastException 异常
            Woman woman = (Woman) per;
            woman.setWomanId(222);
    

    2. 向下转型和instanceof示例Demo

    2.1. 父类 Person

    package tepmdemo.instanseof;
    
    /**
     * @author bruce
     * 
     */
    public class Person {
        protected String name;
        protected int age;
    
        protected void eat() {
            System.out.println("人吃饭");
        }
    
        protected void walk() {
            System.out.println("人走路");
        }
    }
    

    2.2. 子类 Man

    package tepmdemo.instanseof;
    
    /**
     * @author bruce
     *
     */
    public class Man extends Person{
        private int manId;
    
        //重写父类eat方法
        @Override
        public void eat() {
            System.out.println("男人吃饭是为了挣钱");
        }
    
        //重写父类walk方法
        @Override
        protected void walk() {
            System.out.println("男人走路去上班");
        }
    
        //Man子类特有的方法
        protected void setManId(int manId) {
            this.manId = manId;
            System.out.println("男人的ID:"+this.manId);
        }
    }
    

    2.3.子类Woman

    package tepmdemo.instanseof;
    
    /**
     * @author bruce
     * 
     */
    public class Woman extends Person {
        private int womanId;
    
        //重写父类eat方法
        @Override
        protected void eat() {
            System.out.println("女人吃饭是为了购物");
        }
        
        //重写父类walk方法
        @Override
        protected void walk() {
            System.out.println("女人走路去逛街");
        }
    
        //WoMan子类特有的方法
        public void setWomanId(int womanId) {
            this.womanId = womanId;
            System.out.println("女人ID:"+this.womanId);
        }
    }
    

    2.4. 多态向下转型和instanceof

    package tepmdemo.instanseof;
    
    /**
     * @author bruce
     * 
     */
    public class App {
        public static void main(String[] args) {
            System.out.println("--------------------多态的应用-------------------------");
            //对象的多态性:父类的引用指向子类的对象
            Person per = new Man();
            //多态的使用:当调用子父类同名同参数的方法时,实际执行的是子类重写父类的方法 ---虚拟方法调用
            per.walk();
            per.eat();
    
            System.out.println("--------------------向下转型应用-----------------------");
            /**
             * 1.有了对象的多态性以后,内存中实际上是加载了子类特有的属性和方法的,但是由于变量声明为父类类型,导致
             * 编译时,只能调用父类中声明的属性和方法。子类特有的属性和方法不能调用。
             * 2.如何才能调用子类特有的属性和方法?
             * 3.向下转型:使用强制类型转换符,向下转型原理和基本类型的double类型转int类型一样都需要强制装换。
             */
            //强制将Person类型装换为Man类型
            Man man = (Man) per;
            man.setManId(111);
            System.out.println("使用向下转型调用子类特有的属性和方法");
    
            System.out.println("--------------------instanceof关键字-----------------------");
    
            //使用强转时,可能出现 java.lang.ClassCastException 异常
    //        Woman woman = (Woman) per;
    //        woman.setWomanId(222);
    
            /*
             * instanceof关键字的使用
             *
             * a instanceof A:判断对象a是否是类A的实例。如果是,返回true;如果不是,返回false。
             *
             *
             *  使用情境:为了避免在向下转型时出现ClassCastException的异常,我们在向下转型之前,先
             *  进行instanceof的判断,一旦返回true,就进行向下转型。如果返回false,不进行向下转型。
             *
             *  如果 a instanceof A返回true,则 a instanceof B也返回true.
             *  其中,类B是类A的父类。
             */
    
            if (per instanceof Man) {
                Man mans = (Man) per;
                mans.setManId(1);
            }
    
            // 向下转型判断per不属于Woman,不执行里面的语句。
            if (per instanceof Woman) {
                Woman womans = (Woman) per;
                womans.setWomanId(2);
            }
        }
    }
    
    展开全文
  • Java向下转型以及如何判断能否向下转型

    千次阅读 多人点赞 2018-05-11 11:04:37
    那我们怎么样才能既实现向上转型,又能使子类可以调用其独有的方法呢,这就需要使用向下转型了。 注意 向下转型必须是在向上转型之后才能进行。 我们还是以汽车为例。 首先是Car这个父类。...
  • Java向下转型的几种方法

    千次阅读 2019-02-25 17:25:36
    Java向下转型的几种方法 众说周知:Java可以自动向上转型,子对象赋值给父类型,直接可以操作。但是向下转型如何处理呢? 使用场景:对引用的sdk中的API类型进行二次封装,回调接口类型二次封装。说明:这里面的...
  • Java向下转型的意义详解

    千次阅读 多人点赞 2018-10-14 23:29:59
    牢牢记住一句话:无论向上向下转型,编译看左边,运行看右边。 意思就是:编译时候左边的对象有没有该方法(不严谨),运行时候看new的对象是谁,就调用谁的方法   为了解决上述问题,引入强制向下转型: ...
  • ``` package main; class A{ public A() { print();...Exception in thread "main" java.lang.ClassCastException: main.A cannot be cast to main.B ... at main.test1.main(test1.java:31)
  • java 向下转型 父类转子类

    千次阅读 2018-08-22 10:42:29
    向下转型 父类转子类,显示转换,并且必须确保该父类变量是子类的一个实例 例子 class A{} class B extends A{} A a = new A(); A ba = new B(); B ba2 = (B)ba; 因为ba是B的一个实例对象,因此可以向下...
  • 一开始学习 Java 时不重视向下转型。一直搞不清楚向下转型的意义和用途,不清楚其实就是不会,那开发的过程肯定也想不到用向下转型。 其实向上转型和向下转型都是很重要的,可能我们平时见向上转型多一点,向上转型...
  • Java向下转型的条件判断

    千次阅读 2019-05-06 18:46:43
    //抽象类:不允许实例化,可以通过向上转型,指向子类实例 public abstract class Animal { //属性:昵称、年龄 private String name; private int month; public Animal(){ } public ...
  • 一开始学习 Java 时不重视向下转型。一直搞不清楚向下转型的意义和用途,不清楚其实就是不会,那开发的过程肯定也想不到用向下转型。 其实向上转型和向下转型都是很重要的,可能我们平时见向上转型多一点,向上转型...
  • class A{ } class B extends A { } 向下转型: A a = new B(); B b = (B)a; 直接调用子类: B b = new B(); 这两个 b 实例 有什么区别
  • 向下转型时,要捕抓ClassCastException异常,否则会出现异常。尽量少用类型转换与instanceof运算符 对象的类型转换: 1、只能在继承层次内进行类型转换 2、在将超类转换成子类时,应该使用instanceof进行检查 if...
  • 复习java遇到个问题,发现书上向下转型的例子得到的引用和直接实例化子对象得到的引用拥有同样的方法和变量 于是猜测这两种引用得到的内容是相同的 举个例子证明一下 A a=new B(); B b=(B) a; 与 ...
  • 关于java向下转型

    千次阅读 2007-06-29 13:01:00
     // 向下  son.son();  son.father();  } }   这样运行时候会报错 将  Father father = new Father(); 改成 Father father = new Son();就可以输出 i am son'soni am son'sfather ...
  • 看过的一些比较好的博文 Person per = new Student(); //向上转型 Student stu = (Student) per; //向下转型 Java向上转型和向下转型的通俗...Java向下转型的意义 多态的向上转型,向下转型,及instanceof的用法 ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 49,308
精华内容 19,723
关键字:

java向下转型

java 订阅