zoukankan      html  css  js  c++  java
  • 关于java多态

    多态有一种情况是,父类应用指向子类对象:

    父亲 fu = new 儿子();

    这个时候如果父亲中有变量(包括静态和非静态变量)或者静态方法,都不会被儿子覆盖和重写。他们在内存中占用的是两块地方。

    而非静态方法则会被重写。

    内存中该对象的内容:

                父类的成员变量  ①  

                     父类的静态方法  ①

                子类的成员变量 ②

                子类的静态方法 ②

                父类中未被重写的非静态方法 ③ 

                父类中被子类重写的非静态方法 ③          

                                      子类自己新写的方法 ④

    当引用是父类型的时候指向 ① ③

    当引用是子类型的时候指向 ② ③ ④

    引用的类型被强制转换的过程中内存中的数据都是同一组数据。

    所以我们常用的方式是private 属性 加 get set方法方式,这样对大部分人来说不会太乱。

    参考测试代码如下:

    class Fu{
     static int fu = 0;
     int zi = 0;
     public void me(){
      System.out.println("Wo Shi Fu");
     }
     public static void staticMethod(){
      System.out.println("Fu de static method");
     }
    }

    class Zi extends Fu{
     static int fu = 1;
     int zi = 1;
     public void me(){
      System.out.println("Wo Shi Zi");
     }
     public static void staticMethod(){
      System.out.println("Zi de static method");
     }
    }

    public class Test2 {
     public static void main(String[] args) {
      Fu x = new Zi();
      System.out.println(x.fu);
      System.out.println(x.zi);
      x.me();
      x.staticMethod();
      System.out.println("-------------华丽的分割线------------------");  
      //如果这个时候改变x中的变量
      
      x.fu=99;
      x.zi=99;
      
      //强制转换成子对象
      Zi y = (Zi)x;
      System.out.println("-------------强制转换成子类类型后的内容------------------"); 
      System.out.println(y.fu);
      System.out.println(y.zi);
      y.me();
      y.staticMethod();
      System.out.println("-------------华丽的分割线------------------"); 
      
      y.fu = 88;
      y.zi = 88;
      
      System.out.println("-------------强制转换成子类类型后----再次强制转换为父类类型的内容------------------"); 
      Fu a = (Fu)y;
      System.out.println(a.fu);
      System.out.println(a.zi);
      a.me();
      a.staticMethod();
      

      System.out.println("-------------强制转换成子类类型后----再次强制转换为父类类型的内容------------------"); 
      Zi b = (Zi)a;
      System.out.println(b.fu);
      System.out.println(b.zi);
      b.me();
      b.staticMethod();
      
     }

    }

    输出:

    0
    0
    Wo Shi Zi
    Fu de static method
    -------------华丽的分割线------------------
    -------------强制转换成子类类型后的内容------------------
    1
    1
    Wo Shi Zi
    Zi de static method
    -------------华丽的分割线------------------
    -------------强制转换成子类类型后----再次强制转换为父类类型的内容------------------
    99
    99
    Wo Shi Zi
    Fu de static method
    -------------强制转换成子类类型后----再次强制转换为父类类型的内容------------------
    88
    88
    Wo Shi Zi
    Zi de static method

    以上仅代表个人观点,奉劝大家尽信书不如无书,书也是人写的。

    附:

    多态关于反射的拓展:

    package test.test;
    
    import java.lang.reflect.Method;
    
    public class Test2 {
     
        public static void main(String[] args) throws Exception {
            test(new hi());
    }
         
     
        public static void test(Object obj) throws Exception {
            System.out.println(obj);
            Object object = hi.class.newInstance();
            Method mtd = hi.class.getDeclaredMethod("print", null);
            mtd.setAccessible(true);
            mtd.invoke(object, null);
        }
    }
     
    class hi{
        public String toString() {
            return "hi";
        }
        private void print() {
            System.out.println("invokeOk");
        }
    }

    输出结果:

    hi
    invokeOk

    调用test方法时,传入参数相当于Object obj = new hi();

    这个时候内存中是有print方法的,虽然obj没有指向这个方法。

    当用反射调用某个对象的某个方法时的时候,反射技术不会关心这个对象的引用有没有指向指向这个方法,而是关心这个对象所指向的内存中有没有这个方法。

  • 相关阅读:
    4.内核编译和裁剪
    2.Linux技能要求
    3.字符驱动框架
    1.Linux命令
    4.类和抽象
    3.指针
    2.C++语言特性
    1.编译器
    计数排序——Counting Sort
    网关、网桥、路由器、集线器
  • 原文地址:https://www.cnblogs.com/flying607/p/3414425.html
Copyright © 2011-2022 走看看