现在的位置: 首页 > 综合 > 正文

JAVA多态——另解

2018年01月29日 ⁄ 综合 ⁄ 共 1987字 ⁄ 字号 评论关闭

Java引用变量有两个类型:一个是编译时类型,一个是运行时类型。编译时的类型由声明该变量时实用的类型决定,运行时的类型由实际赋给该变量的对象决定

如果编译时类型和运行时类型不一致,就会出现所谓的多态。

因为子类其实是一种特殊的父类,因此Java允许吧一个子类对象直接赋给一个弗雷德引用变量,无需做任何类型转换,或者成为向上转型(upCasting UML图中父类在上),向上转型由系统自动完成,向下转需要显式也就是强制转换。

但把一个之类对象直接赋给父类引用变量,父类 父=new 子类,父类引用变量的编译时类型是父类,而运行时类型是子类。

当运行时调用该变量的方法时,其行为总是想之类方法的行为,而不是父类的方法行为,这将出现相同类型的变量,执行同一个人方法时呈现出不同的行为特征,这就是多态。

引用变量再编译阶段只能调用其编译时类型所具有的方法,但在运行时着则运行它运行时类型所具有的方法(可以通过反射机制来运行时类型所具有的特殊方法)。特别的,对象的属性不具有多态性 。

而向下转型时如Person p = new Student();这行代码将会产生一个p变量,该变量的编译类型为Person,运行时类型是Student,除此之外,还有更极端的情况,程序运行时节收到外部传入的一个对象,该对象的便宜类型是Object,但程序有需要调用该对象运行类型的方法。

为了解决这些问题,程序需要在运行时发现对象和类的真是信息,为了解决这个问题,我们有两种做法:

  • 地重视假设再便宜和运行时都完全知道类型生物具体信息,在这种情况下,我们可以直接显示用instanceof运算符进行判断,再利用强制类型转换将其转换成其运行是类型生物变量即可。
  • 第二种是编译时根本无法获知该对象和类可能输入哪些类,程序职能依靠运行时信息来发现该对象和列的真实信息,这就必须使用反射。
使用反射有两个好处:
  1. 代码更安全,、程序在编译阶段就可以检查需要访问的Class对象是否存在
  2. 程序性能更高,因为这种方式无需调用方法,所以性能更好。
测试程序:
public class Duotai {
 	public int num = 10;
 	public void foo(){
 		System.out.println("Duotai");
 	}
 	public static void main(String[] args) {
 		Duotai duotai = new SubClass();
 		Duotai duotai2 = new SubClass2();
 		duotai.foo();					//对象的方法具备多态性
 		duotai2.foo();
 		System.out.println(duotai.num);	//对象的属性不具备多态性
 		System.out.println(duotai2.num);
 		
 		try {
 			Class<?> clazz = Class.forName("com.znn.cehi.SubClass");//本包
 			Method method = clazz.getMethod("teShu");
 			method.invoke(clazz.newInstance());
 			Method methodPara = clazz.getMethod("teShuPara",int.class,String.class);
 			methodPara.invoke(clazz.newInstance(),111,"sss");
 		} catch (Exception e) {
 			e.printStackTrace();
 		}
 	}
 }
 class SubClass extends Duotai{
 	public int num = 10;
 
 	@Override
 	public void foo() {
 		System.out.println("SubClass");
 	}
 	public void teShu(){
 		System.out.println("子类特有方法");
 	}
 	public void teShuPara(int num,String s){
 		System.out.println("子类特有有参方法"+num+" "+s);
 	}
 }
 class SubClass2 extends Duotai{
 	public int num = 20;
 	
 	@Override
 	public void foo() {
 		System.out.println("SubClass2");
 	}
 	public void teShu(){
 		System.out.println("子类2特有方法");
 	}
 	public void teShuPara(int num,String s){
 		System.out.println("子类2特有有参方法"+num+" "+s);
 	}
 }
运行结果:
SubClass
 SubClass2
 10
 10
 子类特有方法
 子类特有有参方法111 sss

转载请注明:http://blog.csdn.net/qduningning/article/details/8075624

抱歉!评论已关闭.