2013-02-18 91 views
9

我正在學習java。我對繼承有懷疑。當一個子類擴展父類並且父類有一個引用在父類中聲明的實例變量的方法時。但是子類類型的dint覆蓋了這個方法,並且聲明瞭與父類名稱相同的實例變量。在這種情況下,將引用子進程的實例變量或引用父進程。下面的代碼片段Java繼承覆蓋實例變量

class parent { 
    int a; 
    parent() { 
     System.out.println("in parent"); 
     a = 10; 
    } 
    void method() { 
     System.out.println(a); 
    } 
} 
class child extends parent { 
    int a; 
    child() { 
     System.out.println("in child"); 
     a = 11; 
    } 
} 

public class Test { 
    public static void main(String args[]) throws IOException { 
     parent p1 = new child(); 
     p1.method(); 
    } 
} 

我得到的輸出是

在父母
兒童

可有人請讓我明白爲什麼它指父類的實例變量a和不是孩子班的a

另一個疑問是,我明白隱藏方法,當父類和子類中存在靜態方法時,也聲明瞭具有相同簽名的靜態方法。這裏隱藏手段?什麼方法隱藏?如果它的父母方法可以請你解釋一下嗎?
在此先感謝。

+2

你確定你的代碼編譯了嗎?你運行你的代碼? – 2013-02-18 10:00:14

+1

這不應該編譯,父母沒有方法'方法()' – 2013-02-18 10:02:01

+0

抱歉,格式錯誤。現在更新了代碼。 – Mojoy 2013-02-18 10:04:40

回答

17
  1. Java實例變量不能在子類中重寫。 Java繼承不能這樣工作。

  2. 在您的示例中,沒有方法隱藏(或覆蓋或重載)正在進行。

  3. 儘管存在實例變量的隱藏。在child類的a聲明隱藏在parenta的聲明,並在childa所有引用參考child.a不是parent.a

爲了更清楚地說明這一點,嘗試運行此:

public static void main(String args[]) throws IOException { 
    child c1 = new child(); 
    parent p1 = c1; 

    System.out.println("p1.a is " + p1.a); 
    System.out.println("c1.a is " + c1.a); 
    System.out.println("p1 == c1 is " + (p1 == c1)); 
} 

它應該輸出:

p1.a is 10 
    c1.a is 11 
    p1 == c1 is true 

這表明有是兩個不同的領域被稱爲a一個對象.. 。如果訪問允許,你可以獲得它們的兩個值。


最後,您應該學會遵循標準的Java標識符約定。班級名稱應始終以大寫字母開頭。

2

Instance variables are not overriden in sub-class。如果您在班級中定義的變量名稱與您的超類中的變量名稱相同,則稱爲變量的隱藏inheretence and polymorphism不適用於實例變量。如果在parent中定義method()並在Child類中覆蓋它。下面將調用孩子的方法()由於運行時多態性打印

parent p1 = new child(); 
  1. 調用子構造
  2. 與超()調用來調用的父類的構造
  3. 打印在父」 「並初始化Parent的a到
  4. 打印的孩子和初始化Chils a到11

    p1.method();// this invokes Child's method() during run-time 
    
0

問題是您創建了一個子實例並將其存儲在父引用中。因此,當你訪問對象的屬性時,JVM引用父對象的變量值。

如果它是一個子類的引用變量,那麼您將會收到子類的變量值。

以上是Java的一項功能。

0

在創建父實例時。所以在運行時編譯器調用父對象 試試下面的代碼。

public static void main(String args[]) throws IOException { 
    child c1 = new child(); 
    c1.method(); 
} 
1

當你做到這一點

父P1 =新的兒童();

什麼JVM做的是

   first Initialize Parent() 

         || 

       second Initialize Child() 

所以,首先家長構造函數被調用,然後孩子的,但產值11,因爲P1指的是孩子的對象。

1

如你不重寫在子類中,當語句()方法,

parent p1 = new child(); 

執行,方法的父版本()將被執行,並且只知道父類值它自己的一個。因此它會打印一個= 10(因爲它當時在堆棧中)。

最後,你只是將變量a從父類映射到子類。