欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

关于方法的覆写和实例变量的覆盖

程序员文章站 2022-07-13 22:24:58
...
package test;
class A{
	public String field1 = "A.field1";
	protected String field2 = "A.field2";
	String field3 = "A.field3";
	private String field4 = "A.field4";
	
	public String toString(){
		return "public field : " + field1 + " protected field : " + field2
		+" default field : " + field3 + " private String field : " + field4 ;
	}
	
    void toSay(){
	   System.out.println("I am a default method in A!");
   }
    
/*    public void toSay(){
 	   System.out.println("I am a public method in A!");    	
    }*///父类方法的访问的权限不得高于子类的覆写的方法的访问权限 
}


/**
 * 在这里我可以做出一个结论 ,所谓的继承其实就是子类对象拥有父类的对象的一个引用,也就是super关键在,在调用
 * 子类继承了父类的方法的时候如果没有该方法没有被覆写,那么就是用父类对象的引用去调用相应的方法。
 * 如果方法被覆写那么就会调用子类中覆写后的方法,哪怕就是我们不知道真实的子类对象的类型,那么在运行的时候通过保存在
 * 子类对象中的类型信息,也能动态的调用子类的对象覆写后的方法。但是在子类中覆写父类的方法的方法的访问权限不得低于父类
 * 的方法访问的权限,否则编译器出错。 见方法 toSay
 * 不同的是对于子类对象中的实例变量和父类中的实例变量,因为子类的实例变量是对象的组成,因此分布在堆中不同的内存空间中,
 * 也就是拥有不同的内存的地址。因此只要在子类中定义了与父类相同名称的实例变量,那么父类的实例变量就会被覆盖(不管双方的访问权限,不管覆盖的变量的类型),除非我们
 * 通过super(子类对象中保存的父类对象的引用)来调用父类实例变量。当然对于实例变量的调用是不可以多态的,只要子类对象被提升未父类对象,
 * 那么我们就只可以调用父类对象的实例变量,究其原因是因为实例变量的调用关系是在编译的时候确定的,而不像方法的调用是在运行时动态确定的。
 * 
 * @author vagasnail
 *
   2009-4-17   下午02:33:56
 */
class AA extends A{
	public String field1 = "AA.field1";
	   void toSay(){
		   System.out.println("I am a default method in AA!");
	   }
/*	   void toSay(){
		   System.out.println("I am a default method in AA!");
	   } // Error here : Cannot reduce the visibility(可见度) of the inherited(继承的方法) method from A
*/
}
public class TestOverrideAttr {

	public static void main(String[] args) {

		A a = new A();
		a.toSay();   //output : I am a default method in A!
		System.out.println(a.field1);
//		System.out.println(a);
		A aa1 = new AA();
		aa1.toSay(); //output : I am a default method in AA!
		System.out.println(aa1.field1);
		//System.out.println(aa1);
		AA aa2 = new AA();
		aa2.toSay();//output : I am a default method in AA!
		System.out.println(aa2.field1);
		/* System.out.println(aa2);
		 * output:由于在子类中没有覆写基类中的toString()方法,因此这里还是用基类的引用调用的基类的toString()方法。
		 * public field : A.field1 protected field : A.field2 default field : A.field3 private String field : A.field4
		 */
	}


}