[JAVA] 중첩 클래스, 인터페이스

msung99·2022년 5월 24일
0
post-thumbnail

중첩 클래스, 중첩 인터페이스

  • 중첩 클래스 : 클래스안에 클래스가 있는 클래스.
    • 클래스 멤버로 선언된 클래스
    • 안쪽 클래스는 바깥 클래스의 다른 멤버들 이용가능

중첩 클래스의 분류

  • 멤버 클래스 : 멤버가 되는 클래스
    • static 키워드 유뮤에 따라 인스턴스 멤버 클래스, static 멤버 클래스로 나뉨
class A{
  class B{ ... }
}
  • 로컬 클래스 : 바깥 클래스의 메소드 안에 포함되는 클래스
class A{
  void method(){
    class B(){ ... }
  }

인스턴스 멤버 클래스

  • 인스턴스 멤버 클래스(안쪽 클래스)를 사용하기 위해선, 안쪽 클래스는 인스턴스 멤버이므로 반드시 바깥 클래스 객체를 만들어야 사용 가능

  • 안쪽 클래스에 대한 객체를 만들려면 바깥 클래스 객체가 만들어져야 함

class A{
  class B{
    B(){ }
    int field1;
    void method1();
    // static int field2;     => 정적 필드 선언불가능
    // static void method2();
  }
}

A a = new A();  // 안쪽 클래스 B 를 사용하기 위해 바깥 클래스 A 객체를 먼저 생성
A.B b = a.new B();  // 바깥 클래스의 객체 a 의 멤버인 
                    // 안쪽 클래스 B의 생성자를 호출해서 안쪽 클래스 객체 b 를 생성
b.field1 = 3;
b.method1();

static 멤버 클래스

  • static 키워드로 선언된 멤버 클래스

  • static 멤버 클래스 안에 static 필드(변수) 와 메소드를 선언 가능

  • static 멤버는 객체 안만들고 사용 가능.

    • 즉, 바깥 클래스 객체를 안 만들고도 static 멤버 클래스에 대한 객체 생성 가능
class A{
  static class C{
    int field1;
    static int field2;  // 정적 멤버 선언가능
    void method1() { }   
    static void method2() { }  // 정적 메소드 선언가능
  }
}

A.C c = new A.C(); // 보듯이 바깥 클래스 객체 안 만들고 객체 생성가능하다.
c.field1 = 3;  
c.method1();   
A.C.field2 = 3;
A.C.method2();

로컬 클래스

  • 바깥 클래스의 메소드 내부에있는 클래스

예제

class A{
  A() { System.out.println("A 객체 생성됨");
  
  // 인스턴스 멤버 클래스 B
  public class B{
    B() { { System.out.println("B 객체 생성됨"):
    int field1;
    void method1() { }
  }
  
  // static 멤버 클래스 C
  static class C{
    C() { { System.out.println("C 객체가 생성됨"):
    int field1;
    static int field2;
    void method1(){ };
    static void method2() { }
  }
  
  // 로컬 클래스 D
  void method(){
    class D{
      D() { { System.out.println("D 객체가 생성됨"):
      int field1;
      void method1() { }
    }
    D d = new D();
    d.field1 = 3;
    d.method1();
  }
}
main 함수 내용

A a = new A();
A.B b = a.new B();
b.field1 = 3;
b.method1();

A.C c = new A.C();   // static 멤버 클래스의 객체는 바깥 클래스 객체 따로 안만들어도 생성 가능
c.field1 = 3;
c.method1();
A.C field2 = 3;
A.C.method2();

a.method();

바깥 필드와 메소드에서의 접근제한

  • static 은 static 만 사용할 수 있다는 개념을 다시 적용!

  • static 메소드에서는 static 멤버 클래스에 access (ex. static 멤버 클래스로 객체 만들기) 가 가능하지만, 일반 멤버 클래스에는 access 불가능

  • static 은 static 만 사용할 수 있다는 개념을 다시 적용!

  • static 멤버들은 static 멤버 클래스만 사용가능
    하지만 그냥 인스턴스 멤버 클래스는 사용 불가능

  • 반대로 static 멤버 클래스도 static 멤버에만 접근 가능

  • 또한 그냥 인스턴스 멤버 클래스는 모든 멤버에 접근 가능!

public class A{
  B field1 = new B();
  C field2 = new C();
  
  void method1(){
    B var1 = new B();
    C var2 = new C();
  } 
  
 // 아래의 두개의 static 필드와 메소드는 클래스 C에만 접근 가능하다.
 // 인스턴스 멤버 클래스, 필드, 메소드에는 접근 불가능!
 
  static C field4 = new C(); // static 필드(변수)
  
  static void method2(){   // static 메소드
    C var2 = new C();
  }
  
  class B {}  // 인스턴스 멤버 클래스
  static class C {}  // static 멤버 클래스
  
  // 클래스 C는 field4, method2 에만 접근가능.
  // 반면 클래스 B는 모든 멤버에 접근 가능
}
  • 로컬 클래스

    • 로컬 클래스 내부 연산에 사용되는 메소드의 지역변수, 또는 매개변수는 반드시 final 로 설정해야함


중첩 클래스에서 this 사용하기

  • 안쪽 클래스에서 this를 사용하면 안쪽 클래스에 대한 객체를 의미

  • 바깥 클래스에 대해 this 를 사용하고 싶다면

바깥 클래스.this.멤버 형태로 사용할 것

  • this.method() 는 Nested 객체의 메소드를 의미
  • Outter.this.method() 는 Outter 바깥 클래스 객체의 메소드를 의미

중첩 인터페이스

  • 잘 생각해보기~

익명 객체

  • 이름이 없는 1회성 객체
  • 클래스를 상속받았거나, 인터페이스를 구현해야만 생성 가능
    • 상속의 경우 : 자식 객체를 부모타입의 변수에 할당
    • 구현의 경우 : 구현 객체를 인터페이스 타입의 변수에 할당

원래는

부모클래스 변수명 = new 자식 클래스
인터페이스 변수명 = new 구현 클래스

이런 형태일떄 사용하는 것이지만, 자식 클래스와 구현 클래스의 이름이 말 그대로 "익명", 즉 이름이 없으므로 대신에

  1. 부모클래스 변수명 = new 부모 클래스 (){
    (새롭게 선언할 내용)
    (오버라이딩할 내용)
    };

  1. 인터페이스 변수명 = new 인터페이스 () {
    (새롭게 선언할 내용)
    (오버라이딩할 내용)
    };

형태로 선언해 사용하는 것이 익명객체이다.

즉, 이름이 없는 자식객체(구현객체) 를 생성후, 그 객체를 부모타입의 변수(인터페이스 변수) 에 갖다 붙이는 것이다.

ex)
parent p = new parent{

};

자식 클래스에 들어가는 내용이 모두 들어감


예제


  • 익명 객체 내부에 새로 추가된 멤버들은 내부 연산에만 쓰일 수 있고, 외부에서 접근이 불가능함

    • 익명 객체는 자기 이름이 없고, 오로지 자신의 부모 타입을 가지고만 접근한다.

profile
https://haon.blog

0개의 댓글