2012-12-21 69 views
3

我剛開始學習Java,所以如果答案有些明顯,請耐心等待。我做了一些研究,但無濟於事。隱藏屬性的Java字段

據我瞭解,屬性未覆蓋,但只有場隱藏。要確定是否使用超類或子類中的屬性,Java將檢查引用的類型。

那我就不在這裏忍受的輸出:

public class Super { 
    String str = "I'm super!\n"; 

    public String toString() { 
     return str; 
    } 
} 

public class Sub extends Super { 
    String str = "I'm sub.\n"; 
} 

public class TestFH { 
    public static void main(String[] args) { 
     Sub s1 = new Sub(); 

     System.out.printf(s1.toString()); 
    } 
} 

它給我:

I'm super! 

我知道我可以實現我通過方法重載要容易。我只是對發生的事情感到好奇。

在此先感謝。

+0

你期望你的輸出是什麼? –

+0

@RohitJain我期待「我是子」,因爲我從子類引用(這是s1)調用方法。 – Boyang

回答

3

你打電話時,s1.toString(),它的發現,因此使用該方法作爲父類的方法是在子類中可用僅定義在SupertoString()方法。 你的超類方法toString()使用它作爲來自方法的返回值自己的類變量str(在超類初始化值),因此行爲即輸出作爲I'm super!

如果你想得到輸出爲I'm sub.\n那麼你需要重用與超類相同的變量,併爲它賦值新的字符串值,即I'm sub.\n。最好的選擇是使用構造函數爲:

public class Super { 
    String str = "I'm super!\n"; 

    public Super(String stringValue){ 
     this.str = stringValue; 
    } 

    public String toString() { 
     return str; 
    } 
    } 

    public class Sub extends Super { 
    public Sub(){ 
     super("I'm sub.\n"); 
    } 
    } 

    public class TestFH { 
    public static void main(String[] args) { 
     Sub s1 = new Sub(); 
     System.out.printf(s1.toString()); 
    } 
    } 
+0

這就是我想知道的。謝謝! – Boyang

1

此調用使用超類:

Sub s1 = new Sub(); 
System.out.printf(s1.toString()); 

的原因是個子不重寫str,它只是宣稱恰巧有同名的另一個變量。換句話說,sub只是隱藏了變量Super(數據成員不是多態)。

你可以給他們不同的名字,如果他們有不同的含義。或者可以讓Sub使用getter方法訪問(或修改)父級的屬性。

+0

因此,只要我調用超類中定義的方法,它將使用超類的字段,而不是子類的字段? – Boyang

1

你並沒有使用字符串常量,"I'm sub.\n"到共享超領域,你正在創建本地的子場,而是將其分配到這一點。

例如,

public class EncapsulationDemo { 

    public static void main(String[] args){ 
     MySuperObject obj = new MySubObject(); 

     System.out.println(obj); // prints I'm sub. 
    } 

    private static class MySuperObject{ 
     String str = "I'm super."; // protected, can be accessed directly 
            // by subclasses 

     @Override 
     public String toString(){ 
      return str; 
     } 
    } 

    private static class MySubObject extends MySuperObject{ 
     MySubObject(){ 
      super(); 
      str = "I'm sub."; // assign to superclass field 
     } 
    } 
} 

瞭解更多信息,請參閱Controlling Access to Members of a Class

2

你躲在你的子類(陰影)str。由於您的子類中沒有覆蓋toString(),因此正在進行父類的調用,並且它會看到父類的str

如果你這樣做:

public class Sub extends Super { 
    public Sub() { 
     this.str = "I'm sub.\n"; 
    } 
} 

這將輸出你期待什麼。