`

反射与多态

阅读更多

 先自定义一对父类与子类

public class A_For_Reflect_Instance_and_Polymorphism {
	private int my_field=0;
	public void my_method(){
		System.out.println("这是A的方法");
	}
}

 

public class AA_For_Reflect_Instance_and_Polymorphism extends A_For_Reflect_Instance_and_Polymorphism {
	public void my_method(){
		System.out.println("这是AA的方法");
	}
	
	public void not_in_A_method(){
		System.out.println("这是AA的方法.A中没有这个方法");
	}
	
}

  

  A_For_Reflect_Instance_and_Polymorphism 以下简称A。

AA_For_Reflect_Instance_and_Polymorphism以下简称AA。

 

对于多态的普通展示一般有:

A a=new AA();//a的编译时为A。a的运行运行时为AA。a只能使用A中的方法。但实际使用却是AA中继承与重写的方法。
a.my_method();//调用AA中的方法。
a.not_in_A_method();//无法通过编译。

 以上理所当然。

我的疑问来自看到有些人用反射时是这样的。

Class c_a=Class.forName("A");
A a=(A)c_a.newInstance();

 

使用强转来确定a对象。这让我很不爽。因为我觉得这样强转就失去了Java反射的动态意义了。

于是乎就想直接用Object自然的接收newInstance()方法所返回的Object对象。

Class c_a=Class.forName("A");
Object obj=obj.newInstance();

 

但是这样会不会受到编译时类是Object的限制。导致我非Object的方法便不能用了?

如果这样

obj.my_method();

确实无法使用。编译无法通过。

但是使用反射。便可以调用。

Method method1=c_a.getMethod("my_method");
method1.invoke(obj);

 

这样利用Java反射实现动态语言的一些特性便可以实现。只是这代码写起来实在是太冗长了。

 

另外需要说明一下,方法getClass()所得到的是对象运行时类的Class

 

Object obj=new A();
System.out.println(obj.getClass());
//所得到的结果为
// class A

 

 

下面是我实验中的执行代码。

import java.lang.reflect.Method;

public class Reflect_Instance_and_Polymorphism {
	public static void main(String[] args) throws Exception {
		//普通多态
		A_For_Reflect_Instance_and_Polymorphism a_obj=new AA_For_Reflect_Instance_and_Polymorphism();
		a_obj.my_method();
		
		
		System.out.println();
		//反射多态       测试
		Class c=a_obj.getClass();
		System.out.println("obj.getClass返回的类为"+c+"此为运行时类");
		Object obj=c.newInstance();//实例化
		try{
			//obj.my_method();
		}catch(Exception e){
			
		}finally{
			System.out.println("obj在编译时是Object的。obj无法调用my_method。");
		}
		
		System.out.println();
		System.out.println("用反射调用对象的方法");
		Method method1=c.getMethod("my_method");
		method1.invoke(obj);
		System.out.println("用反射即调用运行时方法");
		
		
		Method method2=c.getMethod("not_in_A_method");
		method2.invoke(obj);
		System.out.println("反射调用的方法无视编译时。所调用的方法取决于Class对象所对应的类。");
		
	}
}

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics