1.Java中的隐藏(hide):
问题:
下面的小程序用来演示java中的隐藏,代码如下:
class Base{
public String className = "Base";
}
class Derived extends Base{
private String className = "Derived";
}
public class Test{
public static void main(String[] args){
System.out.println(new Derived().className);
}
}
有人觉得应该打印输出Base,也有觉得Derived类编译报错,因为同名的变量访问控制权限比父类更严格了。
真实情况确实是程序编译有错,但是不是Derived类编译报错,而是在main函数的打印语境中报错,因为Derived类的className属性是私有的,无法访问。
原因:
java中,子类和父类拥有相同方法签名的方法被称为方法覆盖,在方法覆盖中子类方法的访问控制权限不能被父类更严格,同时子类方法也不能抛出被父类方法更多的异常。
而子类和父类拥有同名的变量被称为变量隐藏(hide),变量隐藏没有访问控制权限的限制,因此虽然Base类中的className属性是共有的,子类Derived类可以继承,但是由于子类Derived中拥有同名的className变量,即使是私有的,Derived类的className变量还是会隐藏了父类Base类的className变量。
结论:
如果想要解决上述程序中变量隐藏带来的编译错误,有以下两种解决方法:
方法1:使用类型转换将子类转换父类,代码如下:
class Base{
public String className = "Base";
}
class Derived extends Base{
private String className = "Derived";
}
public class Test{
public static void main(String[] args){
System.out.println(((Base)new Derived()).className);
}
}
此时程序的打印输出结果为Base。
方法2:使用方法覆盖代替变量隐藏,代码如下:class Base{
public String getClassName() {
return "Base";
}
}
class Derived extends Base{
public String getClassName() {
return "Derived";
}
}
public class Test{
public static void main(String[] args){
System.out.println(new Derived().getClassName());
}
}