Java 중첩 클래스와 중첩 인터페이스 #1

jjinny_0609·2023년 2월 22일
0

Java

목록 보기
28/31

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

중첩 클래스(nested class)

클래스 내부에 선언한 클래스를 말한다. 중첩 클래스를 사용하면 두 클르새의 멤버들을 서로 쉽게 접근할 수 있고,
외부에는 불필요한 관계 클래스를 감춤으로써 코드의 복잡성을 줄일 수 있다는 장점이 있다.

자바에서 중첩 클래스는 다른 클래스 내부에 정의된 클래스를 말합니다. 중첩 클래스는 바깥 클래스의 멤버로 간주되며, 바깥 클래스의 인스턴스와 관련된 데이터를 공유할 수 있습니다.

자바에서는 네 가지 유형의 중첩 클래스가 있습니다.

정적 중첩 클래스 (Static Nested Class) : 바깥 클래스의 인스턴스와 관련이 없는 정적 클래스입니다.
인스턴스 중첩 클래스 (Inner Class) : 바깥 클래스의 인스턴스와 관련된 클래스입니다.
지역 중첩 클래스 (Local Class) : 메서드 내부에서 정의되며, 해당 메서드의 블록 내부에서만 사용됩니다.
익명 중첩 클래스 (Anonymous Class) : 클래스의 이름 없이 선언되며, 일반적으로 인터페이스나 추상 클래스의 구현체로 사용됩니다.
중첩 클래스는 코드 구조를 더욱 모듈화하고, 코드 가독성과 유지보수성을 높이는 데 도움을 줍니다. 또한 중첩 클래스는 캡슐화와 정보 은닉을 강화하여 코드 안정성을 향상시킬 수 있습니다.

멤버 클래스 & 로컬클래스

멤버 클래스와 로컬 클래스는 자바에서 중첩 클래스의 두 가지 유형입니다.

  • 멤버 클래스 (Member Class)
    멤버 클래스는 바깥 클래스의 멤버로서 선언되며, 바깥 클래스의 인스턴스 변수와 마찬가지로 바깥 클래스의 모든 멤버에 접근할 수 있습니다. 멤버 클래스는 일반적으로 바깥 클래스의 내부에서만 사용되는 클래스이며, 다른 클래스에서는 잘 사용되지 않습니다. 멤버 클래스는 정적이거나 인스턴스에 속할 수 있으며, 인스턴스 멤버 클래스는 바깥 클래스의 인스턴스를 생성한 후에만 생성될 수 있습니다.

  • 로컬 클래스 (Local Class)
    로컬 클래스는 메서드 내부에서 선언되며, 해당 메서드 내에서만 사용됩니다. 로컬 클래스는 지역 변수와 마찬가지로 메서드 내에서만 유효합니다. 로컬 클래스는 일반적으로 메서드에서 사용할 목적으로 선언되며, 메서드 내에서 클래스의 인스턴스를 생성하여 사용할 수 있습니다. 로컬 클래스는 주로 중첩 클래스의 코드 가독성을 향상시키기 위해 사용됩니다.

바깥 필드와 메서드에서 사용 제한되는 경우

자바에서 중첩 클래스는 바깥 클래스의 멤버로 간주되기 때문에, 중첩 클래스 내부에서는 바깥 클래스의 모든 멤버에 접근할 수 있습니다. 하지만 중첩 클래스 내부에서 바깥 클래스의 멤버를 사용할 때에는 몇 가지 제한사항이 있습니다.

  1. 중첩 클래스에서 바깥 필드와 메서드에 접근할 때, 해당 필드와 메서드는 반드시 final 또는 effectively final 이어야 합니다. effectively final 이란 한 번 초기화되면 값을 변경하지 않는 변수를 말합니다. 이러한 제한은 중첩 클래스가 인스턴스 변수와 메서드를 참조할 때 바깥 클래스의 상태를 변경하지 않도록 하기 위한 것입니다.

  2. 바깥 클래스의 인스턴스를 참조하는 멤버 클래스의 인스턴스를 생성하려면, 반드시 바깥 클래스의 인스턴스가 먼저 생성되어야 합니다. 그렇지 않으면 컴파일 오류가 발생합니다.

  3. 정적 중첩 클래스에서는 바깥 클래스의 인스턴스에 직접 접근할 수 없습니다. 따라서 정적 중첩 클래스에서는 바깥 클래스의 정적 멤버에만 접근할 수 있습니다.

중첩 클래스는 캡슐화와 정보 은닉을 강화하는 데 도움을 주며, 코드 구조를 더욱 모듈화하고 가독성을 높여주는 장점이 있습니다. 하지만 중첩 클래스 내부에서 바깥 클래스의 멤버를 사용할 때에는 위와 같은 제한사항이 있으므로, 주의하여 사용해야 합니다.

예제) 바깥 필드와 메서드에서 사용 제한

예제) 멤버 클래스에서 사용 제한

예제) 중첩 클래스에서 바깥 클래스 참조 얻기

package Ch09;

public class Outter2 { // 바깥 클래스
	// 필드
	String field = "Outer-field";
	// 생성자
	// Outter2(){}
	
	// 메서드
	void method() {
		System.out.println("Outter-method");
	}
	
	class Nested{	// 내부클래스(인스턴스 멤버 클래스)
		// 필드
		String field = "Nested-field";
		// 생성자
		
		// 메서드
		void method() {
			System.out.println("Outter-method");
		}
		
		void print() {
			System.out.println(this.field);
			this.method();
			System.out.println(Outter2.this.field);
			Outter2.this.method();
		}
	}
}

중첩 인터페이스

중첩 인터페이스는 클래스의 멤버로 선언된 인터페이스를 말한다.
인터페이스를 클래스 내부에 선언하는 이유는 해당 클래스와 긴밀한 관계를 맺는 구현 클래스를만들기 위해서 입니다.

class A{
[static] interface I {
	void method();
    }
}

중첩 인터페이스는 인스턴스 멤버 인터페이스와 정적(static) 멤버 인터페이스 모두 가능합니다.
인스턴스 멤버 인터페이스는 바깥 클래스의 바깥 클래스의 객체가 있어야 사용 가능하며, 정적 멤버 인터페이스는 객체 없이 바깥 클래스만으로 바로 접근할 수 있습니다.

정리

class ATest{
	public static void main(String[] args){
	// 바깥 클래스 객체 생성
	A a = new A();
	// 바깥 클래스를 참조하여 인스턴스 멤버 클래스 객체 생성
	A.B b = a.new B();

	//정적 멤버 클래스 객체 생성
	A.B b = new A.B();
	}
}


=============================================
class A{		// 외부 클래스

	int a;  		// 인스턴스 필드
	static int b; 	// 정적 필드
	class B{}		// 내부 클래스
	static class C{	// 내부 클래스
	
	}
	void add(	){ 	// 리턴이 없는 메서드
		int z;	// add메서드 안에 선언했으므로 z변수는 지역변수(로컬변수)
		class E{	// add메서드 안에 선언했으므로 z변수는 지역변수(로컬클래스)
			// 필드
			// 생성자
			// 메서드
		}
	}
}

}

class C{
	public static void main(String[] args){
		// A클래스를 인스턴스화해서 객체 생성
		A a = new A();
		// 인스턴스 필드 x에 접근할 때는 참조변수 a를 통해서 접근.
		a.x = 10;
		// 인스턴스 멤버 클래스에 접근할 때는 바깥클래스 A를 통해 접근
		A.B b = a.new B();
		// 정적 멤버 클래스 C에 접근할 때는 바깥클래스 A없이 접근
		A.C c = new A.C();
	}
}

중첩 클래스와 중첩 인터페이스 확인 문제

  1. 중첩 멤버 클래스에 대한 설명입니다. 맞는 것에 O표, 틀린 것에 X표 하세요.
    ① 인스턴스 멤버 클래스는 바깥 클래스의 멤버 클래스의 객체가 있어야 사용될 수 있다. ( O )
    ② 정적 멤버 클래스는 바깥 클래스의 객체가 없어도 사용될 수 있다. ( O )
    ③ 인스턴스 멤버 클래스 내부에는 바깥 클래스의 필드와 메서드를 사용할 수 있다. ( O )
    ④ 정적 멤버 클래스 내부에는 바깥 클래스의 인스턴스 필드를 사용할 수 있다. ( X )
    정적 멤버 클래스(Static nested class)는 바깥 클래스(outer class)의 인스턴스 필드를 사용할 수 없습니다.

정적 멤버 클래스는 바깥 클래스의 인스턴스와는 독립적으로 존재하며, 바깥 클래스의 인스턴스 필드에 접근할 수 없습니다. 이는 정적 멤버 클래스의 인스턴스가 생성될 때, 바깥 클래스의 인스턴스가 존재하지 않을 수 있기 때문입니다.
만약 바깥 클래스의 인스턴스 필드를 사용해야 하는 경우, 내부 클래스를 non-static으로 선언하면 됩니다. non-static 내부 클래스는 바깥 클래스의 인스턴스와 연관이 있기 때문에, 바깥 클래스의 인스턴스 필드를 사용할 수 있습니다.

  1. 로컬 클래스에 대한 설명으로 틀린 것은 무엇입니까?
    ① 로컬 클래스는 생성자 또는 메서드 내부에 선언된 클래스를 말한다. ( O )
    ② 로컬 클래스도 필드와 생성자를 가질 수 있다. ( O )
    ③ 로컬 클래스는 static 키워드를 이용해서 정적 클래스로 만들 수 있다. ( X )
    ④ final 특성을 가진 매개 변수나 로컬 변수만 로컬 클래스 내부에서 사용할 수 있다. ( X )

  2. 바깥 클래스(NestedClassExample)에서 멤버 클래스의 객체를 생성하는 코드를 빈 칸에 작성해 보세요.

profile
뉴비 개발자 입니다. velog 주소 : https://velog.io/@jjinny_0609 Github 주소 :

0개의 댓글