วัตถุชั้นใน

Sep 19 2020

ฉันไม่เข้าใจพฤติกรรมของโค้ดด้านล่างนี้

ความคาดหวังของฉันคือควรพิมพ์ 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; }
    }
}

คำตอบ

4 Turing85 Sep 19 2020 at 05:26

จากMyInnerมุมมองของมีสองprivate int xฟิลด์ในการเล่นที่นี่:

  • เขตข้อมูลหนึ่งsuper.xที่สืบทอดมาMyOuterแต่ไม่สามารถเข้าถึงได้เนื่องจากถูกประกาศเป็นprivateและMyInnerในฐานะวัตถุที่สืบทอดไม่สามารถเข้าถึงฟิลด์นี้ได้
  • ฟิลด์หนึ่งMyOuter.this.xจากsorrounding MyOuter -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