java 中的 Variable-Shadowing和Variable-Hiding ,是一种处理同名变量在不同作用域内的优先级关系的机制.
java中变量的分类
- 类变量,静态static变量
- 实例变量,定义在类级别的变量字段
- 本地(局部)变量,定义在方法体或代码块中的局部变量
在类的实例方法中定义与实例变量同名的本地局部变量时,将发生Variable-Shadowing现象.在类实例方法内直接使用该变量时,默认为本地局部同名变量,若要使用类实例变量,需要通过this引用.
在继承关系中,子类继承父类的非私有变量,当子类中定义与父类中同名的可继承变量时,在子类的实例中,将发生Variable-Hiding,直接使用同名变量时默认为子类实例变量,若要使用父类中的同名实例变量时,需要通过super引用.
继承关系中的类变量,子类默认继承父类的非私有类变量,且共同持有一份变量值.但子类中定义同名类变量时,父子将分别持有自已的一份类变量,且互不影响.
继承关系示例代码:
// 父类
public class Parent {
//类变量
static Integer age = 38; //测试子类覆盖同名类变量
static Integer grade = 100;//测试子类继承同名类变量
private static String x = "aaa";
//私有实例变量,在子类中不可见,不存在 Variable-Hiding,子类中不能通过super引用
private String private_str = "parent's private instance variable";
//实例变量(Instance Variable)
String name = "parent's instance name";
public void printinstantcevariable_Overid() {
System.out.println("-----parent's printinstantcevariable_Overid--------");
System.out.println("name=" + name);//默认调用实例变量
}
public void printPrivateInstVariable() {
System.out.println("-----parent's printPrivateInstVariable--------");
System.out.println("this.private_str=" + this.private_str);
}
public void printLocalVariable() {
System.out.println("-----parent's printLocalVariable--------");
//本地变量(Local Variable)
String name = "parent's local name";
System.out.println("name=" + name); //调用本地变量
System.out.println("this.name=" + this.name);//需通过this,实现调用实例变量
}
}
//子类
public class Child extends Parent {
//测试覆盖父类的类变量
static Integer age=6;
//测试覆盖父类的实例变量
String name="child's instance name";
//测试覆盖父类的是有变量
private String private_str="child's private instance variable";
@Override
public void printinstantcevariable_Overid(){
System.out.println("-----child's printinstantcevariable_Overid--------");
System.out.println("name= "+name);//无同名本地变量,打印实例变量
System.out.println("super.name= "+super.name);//通过super调用父类的类变量
}
}
public class TestInheritance {
public static void main(String[] args) {
Parent parent =new Parent();
parent.printinstantcevariable_Overid(); //name=parent's instance name
parent.printLocalVariable(); //name=parent's local name , this.name=parent's instance name
parent.printPrivateInstVariable();//this.private_str=parent's private instance variable
System.out.println("################## 1");
Child child=new Child();
child.printinstantcevariable_Overid();//name= child's instance name , super.name= parent's instance name
child.printLocalVariable();// name=parent's local name , this.name=parent's instance name
child.printPrivateInstVariable();//this.private_str=parent's private instance variable
System.out.println("################## 2");
Parent parent1=new Child();
parent1.printinstantcevariable_Overid(); //name= child's instance name ,super.name= parent's instance name
parent1.printLocalVariable();//name=parent's local name , this.name=parent's instance name
parent1.printPrivateInstVariable();//this.private_str=parent's private instance variable
System.out.println("未覆盖的类变量:");
System.out.println(Parent.age );//38
System.out.println(Child.age);//6
child.age++;
System.out.println(Parent.age);//38
System.out.println(Child.age);//7
System.out.println("被覆盖的类变量:");
System.out.println(Parent.grade);//100
System.out.println(Child.grade);//100
Child.grade++;
System.out.println(Parent.grade);//101
System.out.println(Child.grade);//101
Parent.grade++;
System.out.println(Parent.grade);//102
System.out.println(Child.grade);//102
}
}
Shadowing 机制在嵌套类中也存在:
class Shadowing {
// Instance variable or member variable
String name = "Outer John";
// Nested class
// Inner Class
class innerShadowing {
// Instance variable or member variable
String name = "Inner John";
// Method of inner class
// To print the content
public void print(String name)
{
// Print statements
System.out.println(name);
// This keyword refers to current instance
// itself
System.out.println(this.name);
System.out.println(Shadowing.this.name);
}
}
}
// Class 3
// Main class
class TestShadowing {
// Main driver method
public static void main(String[] args)
{
// Accessing an inner class by
// creating object of Outer class inside main()
// method
Shadowing obj = new Shadowing();
Shadowing.innerShadowing innerObj
= obj.new innerShadowing();
// Function Call
innerObj.print("Parameter John");
//分别输出:
//Parameter John
// Inner John
// Outer John
}
}