“สวัสดี อามีโก้!”

“สวัสดี เอลลี่!”

"วันนี้เรามีหัวข้อที่น่าสนใจมาก วันนี้ฉันจะบอกคุณเกี่ยวกับคลาสที่ซ้อนกัน"

"ถ้ามีการประกาศคลาสภายในคลาสอื่น คลาสนั้นจะเป็นคลาสซ้อนกัน คลาสซ้อนแบบไม่คงที่เรียกว่าคลาสภายใน"

"วัตถุของคลาสภายในซ้อนอยู่ภายในวัตถุของคลาสภายนอก และดังนั้นจึงสามารถเข้าถึงตัวแปรของคลาสภายนอกได้"

ตัวอย่าง
public class Car
{
 int height = 160;
 ArrayList doors = new ArrayList();

 public Car
 {
  doors.add(new Door());
  doors.add(new Door());
  doors.add(new Door());
  doors.add(new Door());
 }

class Door()
 {
  public int getDoorHeight()
  {
   return (int)(height * 0.80);
  }
 }
}

"โปรดทราบว่าคลาส Door มีเมธอด getDoorHeight ซึ่งใช้ตัวแปรความสูงของวัตถุ Car และส่งคืนความสูงของประตู"

คลาสที่ซ้อนกัน - 1

"วัตถุประตูไม่สามารถอยู่ได้โดยอิสระจากวัตถุรถยนต์ ท้ายที่สุดมันใช้ตัวแปรของวัตถุรถยนต์ คอมไพเลอร์เพิ่มตัวสร้างและชั้นประตูโดยมองไม่เห็นการอ้างอิงถึงวัตถุรถยนต์ด้านนอก ดังนั้นเมธอดของคลาสประตูด้านใน สามารถเข้าถึงตัวแปรของคลาส Car ภายนอกและเรียกเมธอดของมันได้"

"วัตถุที่ซ้อนกัน สมเหตุสมผลสำหรับฉัน ตัดสินจากแผนภาพ ทุกอย่างค่อนข้างตรงไปตรงมา"

"และมันก็เป็นเช่นนั้น ยกเว้นความแตกต่างเล็กน้อย"

"ชั้นประตูด้านในมีการอ้างอิงถึงวัตถุรถยนต์ ดังนั้น:"

1) คุณไม่สามารถสร้างวัตถุ Door ภายในเมธอดแบบคงที่ของคลาส Car ได้เนื่องจากเมธอดแบบคงที่ไม่มีการอ้างอิงถึงวัตถุ Car ที่ส่งผ่านไปยังตัวสร้าง Door โดยปริยาย

ถูกต้อง ไม่ถูกต้อง
public class Car
{
 public static Door createDoor()
 {
  Car car = new Car();
  return car.new Door();
 }

 public class Door
 {
  int width, height;
 }
}
public class Car
{
 public static Door createDoor()
 {
  return new Door();
 }

 public class Door
 {
  int width, height;
 }
}

2) คลาส Door ไม่สามารถมีตัวแปรหรือเมธอดแบบคงที่ได้

ถูกต้อง ไม่ถูกต้อง
public class Car
{
 public int count;
 public int getCount()
 {
  return count;
 }

 public class Door
 {
  int width, height;
 }
}
public class Car
{

 public class Door
 {
  public static int count;
  int width, height;

  public static int getCount()
  {
   return count;
  }
 }
}

"แล้วถ้าฉันต้องการตัวแปรที่ใช้ร่วมกันโดยอ็อบเจกต์ Door ทั้งหมดล่ะ"

"คุณสามารถประกาศในคลาส Car ได้เสมอ จากนั้นวัตถุประตูทั้งหมดที่ซ้อนอยู่ในวัตถุ Car จะใช้ร่วมกัน"

3) หมายเหตุ: ถ้าคลาสภายในถูกประกาศเป็นสาธารณะ อินสแตนซ์ของมันสามารถสร้างได้นอกคลาสภายนอก แต่ต้องมีอินสแตนซ์ของคลาสภายนอกก่อน:

Car car = new Car();
Car.Door door = car.new Door();
Car.Door door = new Car().newDoor();

4)และอีกหนึ่งความคิดเห็นที่ฉันเกือบลืม

"เนื่องจากเรามีอ็อบเจกต์ที่ซ้อนกันสองออบเจกต์ เมธอดของอ็อบเจ็กต์ภายในจึงสามารถเข้าถึงการอ้างอิงสองรายการที่เรียกว่า 'สิ่งนี้':"

public class Car
{
 int width, height;

 public class Door
 {
  int width, height;

  public void setHeight(int height)
  {
   this.height = height;
  }

 public int getHeight()
 {
  if (height != 0)
   return this.height;
  else
   return (int)(Car.this.height * 0.8);
 }
}

"ฉันจงใจประกาศตัวแปรด้วยชื่อเดียวกันในคลาส"

"ในการเข้าถึงตัวแปรจากคลาสภายนอกเมื่อมันถูกซ่อนไว้ หรือเข้าถึง 'สิ่งนี้' ในคลาสภายใน เพียงเขียน 'YourClassName.this':"

วิธีเข้าถึง 'สิ่งนี้' ของคลาสภายนอก (หรืออื่น ๆ )
Car.this
Car.Door.this
Car.Door.InnerClass2.InnerClass3.this

"ถ้าอย่างนั้น ถ้าเราเขียน 'สิ่งนี้' ในเมธอดของคลาสภายใน 'สิ่งนี้' จะหมายถึงคลาสในใช่ไหม"

"ใช่ ถูกต้อง"

"คุณคิดอย่างไรกับชั้นเรียนภายใน Amigo"

"มันน่าสนใจมาก ฉันไม่อยากบอกว่ามันยากเกินไป"

"มีข้อจำกัดมากมาย แต่ดูเหมือนค่อนข้างมีเหตุผลหลังจากที่คุณอธิบายว่าข้อจำกัดเหล่านั้นมาจากไหนและทำไมมันถึงมีอยู่"

"นอกจากนี้ ฉันได้เขียนคลาสที่ซ้อนกันในงานเป็นเวลาสองเดือน แต่ตอนนี้ฉันเพิ่งรู้ว่าฉันกำลังเขียนอะไรอยู่"

"ขอบคุณสำหรับบทเรียนที่ดี เอลลี"

"ฉันดีใจที่คุณชอบมัน Amigo"