วัตถุชั้นใน
ฉันไม่เข้าใจพฤติกรรมของโค้ดด้านล่างนี้
ความคาดหวังของฉันคือควรพิมพ์ 100 ในทั้งสองprintln()วิธี ทำไมผลลัพธ์ถึงแตกต่างกัน?
ถ้าฉันไม่ใส่ข้อคิดเห็นgetX()ในคลาสชั้นในผลลัพธ์ของprintln() วิธีการจะเหมือนกันซึ่งเป็น 100
ฉันไม่สามารถหาเหตุผลของพฤติกรรมที่แตกต่างกันได้ โปรดช่วยฉันให้เข้าใจ
public class Foo {
public static void main(String[] args) {
MyOuter outerObj = new MyOuter();
MyOuter.MyInner innerObj = outerObj.new MyInner();
innerObj.setX();
System.out.println("x: " + innerObj.getX()); //x: 3
System.out.println("x: " + outerObj.getX()); //x: 100
}
}
class MyOuter {
private int x = 3;
public int getX() { return x; }
class MyInner extends MyOuter {
public void setX(){ x = 100; }
// public int getX() { return x; }
}
}
คำตอบ
จากMyInnerมุมมองของมีสองprivate int xฟิลด์ในการเล่นที่นี่:
- เขตข้อมูลหนึ่ง
super.xที่สืบทอดมาMyOuterแต่ไม่สามารถเข้าถึงได้เนื่องจากถูกประกาศเป็นprivateและMyInnerในฐานะวัตถุที่สืบทอดไม่สามารถเข้าถึงฟิลด์นี้ได้ - ฟิลด์หนึ่ง
MyOuter.this.xจากsorroundingMyOuter-instance (เนื่องจากMyInnerเป็นคลาสภายใน (ไม่คงที่) จึงถูกผูกไว้กับอินสแตนซ์ของสิ่งรอบข้างเสมอMyOuter) ซึ่งสามารถเข้าถึงได้
วิธีการsetX()ในการMyInnerไม่สามารถเข้าถึงข้อมูลสืบทอดsuper.xจึงจะเข้าถึงสนามและการตั้งค่าในการMyOuter.this.x 100โทรติดต่อกันในรอบMyOuter's จะกลับมาgetX()100
การเรียกinnerObj.getX()(ซึ่งสืบทอดมาจากMyOuterและสามารถเข้าถึงได้super.x) จะส่งคืนค่าของฟิลด์ที่สืบทอดมาsuper.x(ยังคงมีค่าเริ่มต้นเป็น3)
ถ้าเราลบextends MyOuterจากและรวมgetX()-method ไว้MyInnerโค้ดจะทำงานตามที่คาดไว้
ความจริงที่ว่าMyInnerไม่สามารถเข้าถึงฟิลด์ที่สืบทอดมาprivate xนั้นสับสนในตอนแรก แต่พฤติกรรมนั้นสอดคล้องกับพฤติกรรมของคีย์เวิร์ดprotectedในบริบทของ mehthods แบบคงที่ในการสืบทอดคลาสตามที่กล่าวไว้ในโพสต์นี้โดย Hariharan