zoukankan      html  css  js  c++  java
  • 【Java学习】向上和向下转型

    https://blog.csdn.net/HuoYiHengYuan/article/details/84855069

    向上转型:将子类转化为父类。

    向下转型:将父类转化为子类。

    继承准备

            下面我们通过例子让读者一步步带入:

            转型是基于继承,所以先实现一个子类继承父类。

    1.  
      /**
    2.  
      * 父类
    3.  
      */
    4.  
      class Father {
    5.  
      String name = "爸爸";
    6.  
      public void sleep() {//睡觉方法
    7.  
      System.out.println(name + "睡觉");
    8.  
      }
    9.  
      }
    10.  
      /**
    11.  
      * 子类继承父类
    12.  
      */
    13.  
      class Son extends Father {
    14.  
      String name = "儿子";
    15.  
      public void p() {//调皮方法
    16.  
      System.out.println(name + "调皮");
    17.  
      }
    18.  
      }

    表现形式

    向上转型

    1.  
      public class UpAndDown {
    2.  
      public static void main(String[] args) {
    3.  
      // 向上转型:将父类引用指向子类对象
    4.  
      Father f = new Son();
    5.  
      f.sleep();//输出“爸爸睡觉”
    6.  
       
    7.  
      //如果f.p();编译出错,不可执行。因为p()不是Father的方法。
    8.  
      }
    9.  
      }

            虽然f是Son对象向上转型得到的,但因为它此时属于Father类,并未实现子类的p()方法,所以不能使用f.p();此时可以看做是一种“瘦身”。

    向下转型

            还是上面的例子,如果再强转为子类。代码如下。

    1.  
      public class UpAndDown {
    2.  
      public static void main(String[] args) {
    3.  
      // 向下转型
    4.  
      Father f = new Son();
    5.  
      ((Son)f).P();//输出“儿子调皮”
    6.  
      }
    7.  
      }

            是不是很惊喜?父类转化为子类,又恢复了子类独有的方法。

            那么,如果我们是直接向下转型呢?

    1.  
       
    2.  
      public class UpAndDown {
    3.  
      public static void main(String[] args) {
    4.  
      // 直接向下转型
    5.  
      Father f = new Father();
    6.  
      f.sleep();//输出“爸爸睡觉”
    7.  
      ((Son)f).P();//报错!!!!!!!!!!
    8.  
      }
    9.  
      }

    看来,向下转型并不耽误父类方法的调用。

    但是,直接向下转型竟然会报错!提示如下:

    Exception in thread "main" java.lang.ClassCastException: lanqiao.Father cannot be cast to lanqiao.Son
        at lanqiao.UpAndDown.main(UpAndDown.java:7)

    意思是说:类型转换异常,Father不能转化为Son。

    这种现象我们可以通俗地理解:

    • 向上转型可以当做隐藏自身的方法,所以,再转回来(向下转型)方法就会恢复原状。该是你的还是你的。
    • 直接向下转型,父类不具有子类的独有方法,所以即使转化成功,也是个残废儿子,还不如不转,所以直接报错转化失败。不是你的你想都别想。

     其实吧,事情是这样的:

    内存中,因为向上转型是父类的引用指向为子类的对象,所以,它只是指向了父类应该拥有的属性和方法,而子类的独有的方法和属性就不指向了(或者说隐藏了),当再强转到子类时。又重新指向了子类对象,那属于它的东西又恢复了。

    来图:


            好了,那么转型有撒子用途呢?

    向上转型和向下转型的使用

    向上转型

    我们这样理解,人都能跳舞,男人和女人跳舞是不一样的。(女装大佬请手下留情!)

    假装有代码:

    假设Person有个dance()跳舞方法。

    Man extends Person      Women extends Person

    此时Man和Women都重写了Person的dance();

    当 Person p = new Man(); p.dance(); //这个时候就是调用男人跳舞的dance方法
    当 Person p = new Woman(); p.dance();// 这个时候就是调用女人的跳舞的dance方法

    这样其实就是一个java的继承,多态. 利于程序扩展. 你需要理解这种设计方式,会让你写出更易维护,简洁的代码。

    向下转型

    灵感不够,拷贝来凑:(不要揍我)

    https://blog.csdn.net/xyh269/article/details/52231944

    package com.company.electronics;
    
    /**
     * @author dxx
     * @date 2020/9/12 10:13
     */
    public class Human {
        public void sleep() {
            System.out.println("Human sleep..");
        }
        public static  void doSleep(Human h){
            h.sleep();
    
        }//此时传递的参数是父类对象,但是实际调用时传递子类对象,就是向上转型。
        public static void main(String[] args) {
            Human h = new Male();// 向上转型
            doSleep(new Male());//此处匿名子类对象,当然实际应用时应该是用上面的向上转型公式,然后将子类对象传递进来,这样以后好在向下转型,此处没有向下转型,所以直接用了匿名类对象。
            doSleep(new Female());
    
        }
    }
    
    class Male extends Human {
        @Override
        public void sleep() {
            System.out.println("Male sleep..");
        }
    }
    
    class Female extends Human {
        @Override
        public void sleep() {
            System.out.println("Female sleep..");
        }
    
    }
    View Code

    https://www.cnblogs.com/buptldf/p/4959480.html

    package com.company.electronics;

    /**
    * @author dxx
    * @date 2020/9/12 10:13
    */
    public class Human {
    public void sleep() {
    System.out.println("Human sleep..");
    }
    public static void doSleep(Human h){
    h.sleep();

    }//此时传递的参数是父类对象,但是实际调用时传递子类对象,就是向上转型。
    public static void main(String[] args) {
    Human h = new Male();// 向上转型
    doSleep(new Male());//此处匿名子类对象,当然实际应用时应该是用上面的向上转型公式,然后将子类对象传递进来,这样以后好在向下转型,此处没有向下转型,所以直接用了匿名类对象。
    doSleep(new Female());

    }
    }

    class Male extends Human {
    @Override
    public void sleep() {
    System.out.println("Male sleep..");
    }
    }

    class Female extends Human {
    @Override
    public void sleep() {
    System.out.println("Female sleep..");
    }

    }
  • 相关阅读:
    Linux下sed,awk,grep,cut,find学习笔记
    Python文件处理(1)
    KMP详解
    Java引用详解
    解决安卓中页脚被输入法顶起的问题
    解决swfupload上传控件文件名中文乱码问题 三种方法 flash及最新版本11.8.800.168
    null id in entry (don't flush the Session after an exception occurs)
    HQL中的Like查询需要注意的地方
    spring mvc controller间跳转 重定向 传参
    node to traverse cannot be null!
  • 原文地址:https://www.cnblogs.com/gtea/p/13697699.html
Copyright © 2011-2022 走看看