关于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没有指向这个方法。

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

原文地址:https://www.cnblogs.com/flying607/p/3414425.html