"안녕, 아미고!"

"안녕, 엘리!"

"오늘은 매우 흥미로운 주제가 있습니다. 오늘은 중첩 클래스에 대해 말씀드리겠습니다."

"클래스가 다른 클래스 내에서 선언되면 중첩 클래스입니다. 비정적 중첩 클래스를 내부 클래스라고 합니다."

"내부 클래스의 개체는 외부 클래스의 개체 안에 중첩되므로 외부 클래스의 변수에 액세스할 수 있습니다."

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);
  }
 }
}

"문 클래스에는 getDoorHeight 메서드가 있습니다. 이 메서드는 Car 객체의 높이 변수를 사용하고 문의 높이를 반환합니다."

중첩 클래스 - 1

"Door 객체는 Car 객체와 독립적으로 존재할 수 없습니다. 결국 Car 객체의 변수를 사용합니다. 컴파일러는 보이지 않게 생성자와 Door 클래스에 외부 Car 객체에 대한 참조를 추가하므로 내부 Door 클래스의 메서드가 외부 Car 클래스의 변수에 액세스하고 해당 메서드를 호출할 수 있습니다."

"중첩된 개체입니다. 이해가 갑니다. 다이어그램으로 판단하면 모든 것이 매우 간단합니다."

"그렇습니다. 몇 가지 뉘앙스를 제외하고."

"내부 Door 클래스에는 Car 개체에 대한 참조가 있으므로 다음과 같습니다."

1) Car 클래스의 정적 메서드 내에서 Door 개체를 만들 수 없습니다. 정적 메서드에는 Door 생성자에 암시적으로 전달되는 Car 개체에 대한 참조가 포함되어 있지 않기 때문입니다.

옳은 잘못된
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 개체에 중첩된 모든 Door 개체에서 공유됩니다."

3) 참고: 내부 클래스가 공개로 선언된 경우 외부 클래스 외부에서 인스턴스를 만들 수 있지만 외부 클래스의 인스턴스가 먼저 존재해야 합니다.

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

4) 그리고 거의 잊어버릴 뻔한 댓글이 하나 더 있습니다.

"두 개의 중첩된 개체가 있으므로 내부 개체의 메서드는 'this'라는 두 개의 참조에 액세스할 수 있습니다."

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);
 }
}

"클래스에서 일부러 같은 이름으로 변수를 선언했습니다."

"숨겨진 외부 클래스의 변수에 액세스하거나 내부 클래스 내부의 'this'에 액세스하려면 간단히 'YourClassName.this'를 작성하십시오."

외부(또는 다른) 클래스의 'this'에 액세스하는 방법
Car.this
Car.Door.this
Car.Door.InnerClass2.InnerClass3.this

"그러면 내부 클래스의 메서드 안에 'this'를 쓰면 'this'가 내부 클래스를 가리킵니까?"

"네. 맞습니다."

"이너 클래스에 대해 어떻게 생각해, 아미고?"

"매우 흥미롭습니다. 너무 어렵다고 말할 수는 없습니다."

"많은 제한이 있지만 이러한 제한이 어디에서 왔으며 왜 존재하는지 설명하면 상당히 논리적으로 보입니다."

"또한 두 달 동안 작업에 중첩된 클래스를 작성해 왔지만 이제서야 내가 실제로 무엇을 작성했는지 깨닫습니다."

"훌륭한 교훈을 주셔서 감사합니다, Ellie."

"좋아해줘서 다행이야, 아미고."