无意中发现的这个有趣的问题。

观察下列代码, 父类和子类中都定义有 String name变量,那最终继承之后是不是只剩下1个name?还是父类子类的name互相不相干?

通过赋值后,最后会输出什么?见如下

public class Son extends Parent{
    String name;                // 子类中的name  
    void value(){  
        name ="a";   
        super.value();          //调用父类中的value(),给name赋值b  
        System.out.println(name);       //结果输出 a  
        System.out.println(super.name); //结果输出 b  
                }  


 public static void main (String[] args){
     TestTest test =new TestTest();
     test.value();
                                       }
                               }//end class 

 class Parent{<span style="white-space:pre">				</span>       //定义父类
		String name;                   //父类中的name
		void value (){
			name = "b";
		             }
	            }//end class



输出:

a


由此可见,子类首先 name=“a”,即使调用了父类value()中的 name ="b", 


System.out.println(name);  仍然是输出 a  ,可见子类通过引用父类方法并不改变子类中的name的值,即使赋值的变量名都是name


然而,改变的是父类中自己的name变量,因此System.out.println(super.name);输出 b  


综合得知,父类与子类定义同名的变量,并不会覆盖,而是各自还有自己的空间,即使变量名相同


子类中调用父类的对同名变量name赋值的方法,仍然只是改变父类自己的name变量的值




再看一个,结合父类引用,多态问题


public class Son_test extends Parent
	{

		int i = 10;

		public static void main(String[] args)
			{

				Son_test son_test = new Son_test();

				System.out.println("son.i=" + son_test.i);//输出子类的 i=10;
				
				son_test.set(100);                        //  调用继承的父类方法,由上可知,改变的只是父类自己的 i
				System.out.println("son.i=" + son_test.i); //    输出的仍然是 子类的 i=10
				
				
				Parent son =son_test;                   // 多态,子类对象赋值给父类引用,  引用类型是父类Parent 
				System.out.println( son.i);             // 输出的竟然是父类的 i=100 ,,,,,,,
				
			}

		
	}


class Parent
	{

		int i = 10;

		public void set(int i)
			{

				this.i = i;
			}
	}

输出:

son.i=10
son.i=10
100


由此可见,当父类子类存在同名变量时,引用类型是父类,即使是子类的对象,son.i 中的  i 却是 父类中的 i 。



分界线



我们知道,如 Parent a = new Son();   其中son的父类是parent,  利用引用 a.变量   或者  a.方法时候,即使son类中有对应的变量或方法,而父类parent 中没有a.变量   或者   a.方法,是不能通过编译的,



但若父类parent 中存在对应的 变量和方法 ,son子类中也有同名的变量和方法, 则a.方法  调用的是子类的方法,而  a.变量 调用的确是 父类的变量。


见如下代码

public class A {
	Animal  animals = new Dog();
	Dog  dogs =  new Dog();

	public static void main(String[] args) {
              A as =new A();
     
              as.go2();
	                                       }

	
        void go2(){
	animals.eat();                 // Animal animals =new Dog(),父类应用类型,子类对象
	System.out.println(animals.i);
                  }

	

//内部类
 class Animal  {
 	        int i=10;             //子类的i
		void eat() {
			System.out.println("animal are eating");
		           }
	       }

 class Dog extends Animal {
		int i=100;            //父类的i
		void eat() {
			System.out.println("dogs are eating");
		           }

	                          }







输出:

dogs are eating  (  animal.eat() 调用的是子类的 eat()  )

10 (   animal.i  调用的是父类的 i )