继承关系 - 成员变量
问题
子类能否继承父类成员变量,能否覆盖。
实验
设子类 Child,父类 Parent
子类能否继承父类成员变量
Parent.java
public class Parent {
String name;
public Parent() {
this.name = "Parent";
}
}
Child.java
public class Child extends Parent {
public static void main(String[] args) {
Child child = new Child();
System.out.println(child.name);
}
}
输出是: Parent
能否在子类中覆盖父类成员变量
Child.java
public class Child extends Parent {
public String name;
public Child(){
this.name = "Child";
}
public static void main(String[] args) {
Child child = new Child();
System.out.println(child.name);
}
}
输出是: Child
父类的引用变量
Child.java:
public class Child extends Parent {
public String name;
public Child(){
this.name = "Child";
}
public static void main(String[] args) {
Parent child = new Child();
System.out.println(child.name);
}
}
输出是:Parent
这是唯一让我疑惑的地方。通过阅读 java编程思想 知晓了原因。
下面这种形式称为多态:
Parent child = new Child();
这里,把child视为Parent类的对象,称为向上转型。因为在继承树种,基类是在上方的。
多态的好处在于,前期你可以针对基类编写方法,而具体的实现可以由具体的子类承担。由于方法是针对基类的,所以也可以基于子类工作,因为它们具有相同的接口(不包括子类新添加的接口)。
当使用多态的时候,方法是在运行期绑定的(绑定为真实类型的方法),而成员变量是在编译器绑定的(绑定引用变量类型的成员变量),称为早绑定。
所以这里,输出是 Parent 对象的成员变量。
如果通过方法访问变量呢?
public class Parent {
String name;
public Parent() {
this.name = "Parent";
}
public String getName(){
return this.name;
}
}
public class Child extends Parent {
public String name;
public Child(){
this.name = "Child";
}
public static void main(String[] args) {
Parent child = new Child();
System.out.println(child.getName());
}
}
输出依然是 Parent。
如果Child也实现 getName:
public class Child extends Parent {
public String name;
public Child(){
this.name = "Child";
}
public String getName(){
return this.name;
}
public static void main(String[] args) {
Parent child = new Child();
System.out.println(child.getName());
}
}
输出变成了 Child
这是因为前一种getName方法会引用父类的(因为子类没有),后一种引用子类的,而方法访问的显然是本对象的name变量。
总结
子类会继承父类的成员变量,也能够覆盖。当使用多态方法创建子类对象时,直接访问的变量是父类的成员变量。
实际使用中,很少会出现以上情况。首先,变量一般都会定义成private,所以只能在方法内部访问,不能直接访问,这就避免了多态时候的不一致问题。而且,一般也不会定义同名变量,这就不会出现覆盖问题。这些都可以通过良好的代码习惯避免。