在编写子类时,我们可以声明成员变量。一种特殊的情况就是,所声明的成员变量的名字和从父类继承来的成员变量的名字相同,在这种情况下,子类会隐藏所继承的成员变量。
Goods类:
public class Goods {
double weight;
public void oldSetWeight(double w) {
weight=w;
System.out.println("double型的weight="+weight);
}
public double oldGetPrice() {
double price=weight;
return price;
}
}
CheapGoods类,继承Goods类:
public class CheapGoods extends Goods{
int weight;
public void newSetWeight(int w) {
weight=w;
System.out.println("int型的weight="+weight);
}
public void setHeight(int w) {
this.weight=w;
super.weight=w;
}
public double newGetPrice() {
double price=weight;
return price;
}
}
这里Goods类有weight变量,CheapGoods子类也有weight变量,所以Goods类的weight被隐藏。
CheapGoods继承了Goods类,CheapGoods对象有Goods类的double类型的weight(被隐藏),也有cheapGoods类的int类型的weight,有oldSetWeight,oldGetPrice,newSetWeight,SetHeight,newGetPrice有5种方法
测试类:
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
CheapGoods cheapGoods=new CheapGoods();
//cheapGoods.weight=198.98; 报错
//cheapGoods有两个成员变量
//一个是父类Goods中的weight,一个是子类CheapGoods中的weight
//Goods的weight被隐藏,cheapGoods.weight只能是int类型,所以报错
//cheapGoods类中的weight设置为198
//此时Goods类中的weight还没有被赋值,double类型默认为0.0
cheapGoods.newSetWeight(198);
System.out.println("cheapGoods用newGetPrice方法得到的价格为"+cheapGoods.newGetPrice());
System.out.println("cheapGoods用oldGetPrice方法得到的价格为"+cheapGoods.oldGetPrice());
//Goods类中的weight设置为198.987
cheapGoods.oldSetWeight(198.987);
System.out.println("cheapGoods用newGetPrice方法得到的价格为"+cheapGoods.newGetPrice());
System.out.println("cheapGoods用oldGetPrice方法得到的价格为"+cheapGoods.oldGetPrice());
System.out.println();
cheapGoods.setHeight(98);
System.out.println("cheapGoods用newGetPrice方法得到的价格为"+cheapGoods.newGetPrice());
System.out.println("cheapGoods用oldGetPrice方法得到的价格为"+cheapGoods.oldGetPrice());
}
}
//程序输出结果为:
// int型的weight=198
// cheapGoods用newGetPrice方法得到的价格为198.0
// cheapGoods用oldGetPrice方法得到的价格为0.0
// double型的weight=198.987
// cheapGoods用newGetPrice方法得到的价格为198.0
// cheapGoods用oldGetPrice方法得到的价格为198.987
//
// cheapGoods用newGetPrice方法得到的价格为98.0
// cheapGoods用oldGetPrice方法得到的价格为98.0
在测试类中,输入cheapGoods.weight=198.98,会报错,是因为Goods类的weight被隐藏了,cheapGoods只能使用cheapGoods的weight,而cheapGoods的weight是int类型,198.98是double类型,所以会报错。
newSetWeight方法改变的是子类CheapGoods的weight(int),newGetPrice输出子类CheapGoods的weight(int)。oldSetWeight改变父类Goods的weight(double),oldGetPrice输出父类Goods的weight(double)。
子类从父类继承的方法只能操作子类继承的变量和被子类隐藏的变量。子类新定义的方法可以操作子类继承和子类新声明的成员变量,但无法操作子类隐藏的成员变量(需要使用super关键字)
其实,我们可以这样理解上述的话,我们知道,在一个类中使用成员变量时,编译器会自动在成员变量前面加一个this,即this.成员变量。我们把Goods类和CheapGoods类再重新写一下
Goods类:
public class Goods {
double weight;
public void oldSetWeight(double w) {
this.weight=w;
System.out.println("double型的weight="+this.weight);
}
public double oldGetPrice() {
double price=this.weight;
return price;
}
}
CheapGoods类,继承Goods类:
public class CheapGoods extends Goods{
int weight;
public void newSetWeight(int w) {
this.weight=w;
System.out.println("int型的weight="+this.weight);
}
public void setHeight(int w) {
this.weight=w;
super.weight=w;
}
public double newGetPrice() {
double price=this.weight;
return price;
}
}
this可以直接看成所在类的对象。
cheapGoods调用newSetHeight,newSetHeight中的this是在CheapGoods类中的。所以它改变的是CheapGoods类的weight(int).
cheapGoods调用oldSetHeight,oldSetHeight中的this是在Goods类中的,所以它改变的是Goods类的weight(double),别的函数也一样,这里就不一个一个解释了
当子类想要使用被隐藏的成员变量的时候,可以使用super关键字调用,就像CheapGoods类中的setHeight方法一样.
感觉在编写子类的时候,就应该尽量避免子类有和父类一样的成员变量。非要隐藏父类的成员变量,只会增加程序的阅读难度。
==============================================================================
现在回头看看,感觉用this来解释,有点牵强。大家将就着看看吧