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

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

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