无意中发现的这个有趣的问题。
观察下列代码, 父类和子类中都定义有 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 )