首页 > 代码库 > java继承和多态

java继承和多态

java方法直接调用原理推测 有错误还望指正

当直接调用某对象的某方法时  会更具该对象获取到类信息对象   在从类信息对象中找到该方法 没找到 获取父类信息对象继续查找 找到了执行  jdk距离实现是通过反射还是其它?

如果按以上原理    以下情况解释不通 

创建一子类对象  赋值给一父类指针变量  通过父类指针变量掉run方法   run方法在父类或子类中为私有  这种情况调用的是父类的run方法 并非子类的run方法 


反射jar包

package extend;

import org.junit.Test;

import cn.nailsoul.reflect.util.ReflectUtil;

public class extendTest {
	@Test
	public void testAcccessMembers(){
		System.out.println("===========testAcccessMembers===========");
		//在父类中直接修改属性修改的永远都是父类的属性 
		Persion p = new Student();
		p.setName("Perion.name:"+"张三"+" Student.name:"+((Student)p).name);
		System.out.println(p.getName());
		
		//修改属性时 修改的是左边声明的那个类中定义的属性 跟被修改的对象所属类中定义的属性无关
		p.age=25;
		System.out.println("Perion.age:"+p.age+" Student.age:"+((Student)p).age);
	
		//在调用某方法时  该方法在子类或父类中为私有的话 则不是方法覆盖 调用的为左边声明的类中的方法
		// 只有子类和父类中该方法同时不为私有的时候 才为方法覆盖 子类有执行子类的方法 子类没有才执行父类的方法 
		//在父类中调用某方法同样遵循上面这一特性
		p.privateSay();
		p.publicSay();
		p.run();
	}

	@Test
	public void testReflectAccessMembers() throws Exception{
		//反射调用方法和直接调用方法结果一样
		//在反射某方法时  该方法在子类或父类中为私有的话  调用被反射类的方法
		//只有子类和父类中该方法同时不为私有的时候 调用被反射对象的方法
		System.out.println("===========testReflectAccessMembers===========");
		Student stu = new Student();
		ReflectUtil.callMethod("privateSay",null, null, Persion.class, stu, false);
		ReflectUtil.callMethod("publicSay",null, null, Persion.class, stu, false);
	
		ReflectUtil.callMethod("privateSay",null, null, Student.class, stu, false);
		ReflectUtil.callMethod("publicSay",null, null, Student.class, stu, false);
		
		//当被反射的类中找不到要反射方法时抛异常 要反射的类信息对象中没有要反射的父类的方法信息  
		//A类信息对象中只保存A类的信息  不报错A类的父类的信息   所有方法代码都保存在方法区  通过A类信息对象 可以找到A类在方法区中的所有A类中的方法代码
//		ReflectUtil.callMethod("setName",new Class[]{String.class}, "张三", Student.class, stu, false);
		
		//反射修改属性时 修改的是被反射的那个类中定义的属性跟被反射对象所属类中定义的属性无关
		ReflectUtil.setFieldValue("age", 30, Persion.class, stu, false);
		System.out.print("Reflect.age:" + ReflectUtil.getFieldValue("age", Persion.class, stu, false));
		System.out.println("  Persion.age:"+((Persion)stu).age+" Student.age"+stu.age);
		
		stu=new Student();
		ReflectUtil.setFieldValue("age", 30, Student.class, stu, false);
		System.out.print("Reflect.age:" + ReflectUtil.getFieldValue("age", Student.class, stu, false));
		System.out.println("  Persion.age:"+((Persion)stu).age+" Student.age"+stu.age);
		
		//当被反射的类中找不到要反射属性时抛异常 要反射的类信息对象中没有要反射的父类的属性信息  
//		ReflectUtil.setFieldValue("money", 30, Student.class, stu, false);
	}

	public class Persion {
		protected String name;
		private int age;
		public long money;

		public String getName() {
			System.out.println("Persion.getName()");
			return name;
		}

		public void setAge(int age) {
			System.out.println("Persion.setAge()");
			this.age = age;
		}

		public void setName(String name) {
			System.out.println("persion.setName()");
			this.name = name;
		}

		public int getAge() {
			System.out.println("persion.getAge()");
			return age;
		}
		
		private void privateSay() {
			System.out.println("Persion.privateSay()");
		}
		void publicSay() {
			System.out.println("Persion.publicSay()");
		}
		void run(){
			System.out.println("Persion.run()");
			privateSay();
			publicSay();
		}
	}

	public class Student extends Persion {
		protected String name;
		private int age;

		public void setAge(int age) {
			System.out.println("Student.setAge()");
			this.age = age;
		}

		public int getAge() {
			System.out.println("Student.getAge()");
			return age;
		}

		private void privateSay() {
			System.out.println("student.privateSay()");
		}
		void publicSay() {
			System.out.println("student.publicSay()");
		}
	}
}


运行结果

===========testReflectAccessMembers===========
Persion.privateSay()
student.publicSay()
student.privateSay()
student.publicSay()
Reflect.age:30  Persion.age:30 Student.age0
Reflect.age:30  Persion.age:0 Student.age30
===========testAcccessMembers===========
persion.setName()
Persion.getName()
Perion.name:张三 Student.name:null
Perion.age:25 Student.age:0
Persion.privateSay()
student.publicSay()
Persion.run()
Persion.privateSay()
student.publicSay()