继承关系 - 成员变量

问题

子类能否继承父类成员变量,能否覆盖。

实验

设子类 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,所以只能在方法内部访问,不能直接访问,这就避免了多态时候的不一致问题。而且,一般也不会定义同名变量,这就不会出现覆盖问题。这些都可以通过良好的代码习惯避免。

posted @ 2015-09-19 16:42  六月的海  阅读(297)  评论(0编辑  收藏  举报