當(dāng)前位置:首頁(yè) > 嵌入式培訓(xùn) > 嵌入式學(xué)習(xí) > 講師博文 > 方法和變量在繼承時(shí)的覆蓋和隱藏問(wèn)題
近有個(gè)同學(xué)問(wèn)了我一個(gè)小問(wèn)題,覺(jué)得很有意思,之前一直沒(méi)有想到過(guò)。他說(shuō)“java中存在方法覆蓋,是否存在變量的覆蓋呢?”。我們知道,在java中,子類可以繼承父類,如果子類聲明的方法與父類有重名,這時(shí)就發(fā)生了方法覆蓋。其實(shí),這實(shí)際上這又分為兩種情況,就是方法和變量在繼承時(shí)的覆蓋和隱藏問(wèn)題,這些概念性的東西看似無(wú)聊,但是在面試中還是比較常見(jiàn)的,所以這里來(lái)討論下
首先我們來(lái)看幾個(gè)概念
隱藏 :子類隱藏了父類的變量和方法,那么,子類不能訪問(wèn)父類被隱藏的變量或者方法,但是,將子類轉(zhuǎn)換成父類,可以訪問(wèn)父類被隱藏的變量或者方法
覆蓋 :子類覆蓋了父類的變量或者方法,那么,子類不能訪問(wèn)父類被覆蓋的變量或者方法,將子類轉(zhuǎn)換成父類后同樣不能訪問(wèn)父類被覆蓋的變量或者方法
首先看一下JAVA中方法和變量在繼承時(shí)的覆蓋和隱藏規(guī)則
1.父類的實(shí)例變量和靜態(tài)變量能被子類的同名變量隱藏
2.父類的靜態(tài)方法被子類的同名靜態(tài)方法隱藏
3.父類的實(shí)例方法被子類的同名實(shí)例變量覆蓋
還有幾點(diǎn)需要注意的是
1.不能用子類的靜態(tài)方法隱藏 父類中同樣標(biāo)示(也就是返回值 名字 參數(shù)都一樣)的實(shí)例方法
2.不能用子類的實(shí)例方法覆蓋 父類中同樣標(biāo)示的靜態(tài)方法
3.這點(diǎn)兒請(qǐng)注意,就是變量只會(huì)被隱藏 不會(huì)被覆蓋 ,無(wú)論他是實(shí)例變量還是靜態(tài)變量,而且,子類的靜態(tài)變量可以隱藏 父類的實(shí)例變量,子類的實(shí)例變量可以隱藏 父類的靜態(tài)變量
創(chuàng)建兩個(gè)父子類關(guān)系的類
Java代碼
//父類
class Parent
{
public static String kind="cn.com.farsight.parent";
public static int age=50;
public String name="Parent";
//靜態(tài)方法,返回包名
public static String getKind()
{
System.out.println("parent的getKind()方法被調(diào)用了");
return kind;
}
//靜態(tài)方法,返回年齡
public static int getAge()
{
System.out.println("Parent的getAge()方法被調(diào)用了");
return age;
}
//實(shí)例方法,返回姓名
public String getName()
{
System.out.println("Parent的getName()方法被調(diào)用了");
return this.name;
}
}
//子類
class Child extends Parent
{
public static String kind="cn.com.farsight.child";
public int age=25;
public String name="child";
//隱藏父類靜態(tài)方法
public static String getKind()
{
System.out.println("child的getkind()方法被調(diào)用了");
return kind;
}
//獲取父類包名
public static String getParentKind()
{
return Parent.kind;
}
//覆蓋父類實(shí)例方法
public String getName()
{
System.out.println("child的getName()被調(diào)用了");
return this.name;
}
//獲取父類名稱
public String getParentName()
{
return super.name;
}
/*
*錯(cuò)誤,實(shí)例方法不能覆蓋父類的靜態(tài)方法
public int getAge()
{
return this.age;
}
*/
}
class TestDemo
{
public static void main(String[] args)
{
Child child=new Child();
System.out.printf("子類名稱:%s,年齡:%d,包名:%s%n",child.name,child.age,child.kind);
//輸出:子類名稱:child,年齡:25,包:cn.com.farsight.child
//把child轉(zhuǎn)換成parent對(duì)象
Parent parent=child;
System.out.printf("轉(zhuǎn)換后的名稱:%s,年齡:%d,包名:%s%n",parent.name,parent.age,parent.kind);
//輸出:轉(zhuǎn)換后的名稱:Parent,年齡:50,包:cn.com.farsight.parent
System.out.printf("子類訪問(wèn)父類被隱藏的實(shí)例變量name:%s%n",child.getParentName());
//輸出:子類訪問(wèn)父類被隱藏的實(shí)例變量name:Parent
System.out.printf("子類訪問(wèn)父類被隱藏的靜態(tài)變量kind:%s",child.getParentKind());
//輸出:子類訪問(wèn)父類被隱藏的靜態(tài)變量kind:cn.com.farsight.parent
child.getName();
//輸出:child的getName()被調(diào)用了
//**************注意看這個(gè)方法,返回的還是子類的getName
parent.getName();
//輸出:child的getName()被調(diào)用了
child.getKind();
//輸出:child的getkind()方法被調(diào)用了
parent.getKind();
//輸出:parent的getKind()方法被調(diào)用了
}
}
總結(jié):
1.同名的實(shí)例方法被覆蓋 ,同名的靜態(tài)方法被隱藏 ,child類的getName實(shí)例方法覆蓋 了parent的getName實(shí)例方法,chind的getKind方法隱藏了parent類的getKind方法
2.隱藏和覆蓋的區(qū)別在于,子類對(duì)象轉(zhuǎn)換成父類對(duì)象后,能夠訪問(wèn)父類被隱藏 的變量和方法,而不能訪問(wèn)父類被覆蓋的方法
3.如果需要訪問(wèn)父類被隱藏的實(shí)例變量,加上super就好了,比如訪問(wèn)父類name,使用super.name