The Debugging Chronicles : "코드의 미학"

Mentor JAVA - section13. 내부 클래스 본문

JAVA/Mentor JAVA

Mentor JAVA - section13. 내부 클래스

sweetseonah1004 2024. 7. 24. 14:07

내부 클래스

- 클래스 안에 만들어진 또 다른 클래스를 말하며, 다른 말로 중첩 클래스라고도 말한다.

- 바깥쪽의 클래스를 '외부 클래스', 안쪽의 클래스를 '내부 클래스'라고 하며, 두 개의 클래스는 서로 긴밀한 관계를 가지고 있다.

- 내부 클래스는 외부 클래스 안에 선언된다는 점만 제외하면 일반 클래스와 같은 성격과 모습을 지니고 있다.

 
public class 외부클래스명 { ... class 내부클래스명 { ... } }

- 장점

· 두 클래스 멤버들 간에 손쉽게 접근할 수 있다.

· 불필요한 클래스를 감춰서 코드의 복잡성을 줄일 수 있다.

내부 클래스의 종류

▶ 선언된 위치에 따라 구분된다.

- 인스턴스 클래스(instance class)

· 외부 클래스 내부에서 생성하고, 선언되어 사용하는 클래스를 의미한다.

· 인스턴스 변수와 같은 위치에 선언하며, 외부 클래스의 인스턴스 멤버처럼 다루어진다.

· 외부 클래스의 인스턴스 멤버들과 관련된 작업에 사용될 목적으로 선언한다.

· 인스턴스 클래스는 외부 클래스의 인스턴스 변수를 사용할 수 있으나 정적 변수나 메서드를 호출할 수는 없다.

· 생성

public class 외부클래스명 { private 자료형 변수명; // 인스턴스 멤버 ex) private String name; ... public class 내부클래스명 { private 자료형 변수명; ex) private String name; ... } }

내부 크래스도 외부 클래스 안에 생성될 뿐 별도의 클래스이기 때문에, 파일이 컴파일되면 별도로 생성된다.

 

$ 기호를 기준으로 왼쪽이 외부 클래스, 오른쪽이 내부 클래스

· 선언

인스턴스 클래스는 기본적인 내부 클래스이므로, 외부 클래스 객체가 생성된 상태에서 객체를 생성할 수 있다.

외부 클래스가 반드시 선언된 후, 외부 클래스의 인스턴스를 이용해 선언한다.

Outer outer = new Outer(); // 외부 클래스 객체 생성 Outer.Inner in = outer.new Inner(); // 외부 클래스를 이용하여 내부 클래서 객체 생성

- 정적 클래스 (static class)

· static 키워드를 사용해 클래스를 선언한 후 정적 내부 클래스를 생성한다.

· 주로 외부 클래스의 static 메서드에서 사용될 목적으로 선언된다.

· 정적 변수와 마찬가지로 클래스에 속하지만 독립적을 존재한다.

· 외부 클래스의 존재와 상관없이 정적 변수, 정적 메서드를 호출하는 것은 가능만,

외부 클래스의 인스턴스 변수 또는 메서드를 정적 내부 클래스 안에서는 사용할 수 없다.

· 생성

public class 외부클래스명 { private 자료형 변수명; // 인스턴스 멤버 ex) private String name; ... public static class 내부클래스명 { private 자료형 변수명; ex) private String name; ... } }

인스턴스 멤버와 동일한 위치에 선언한다.

· 선언

외부 객체를 생성하지 않아도 선언할 수 있다.

Outer.Inner in = outer.new Inner(); // 외부 클래스 없이 바로 객체 생성

- 지역 클래스 (local class)

· 외부 클래스의 메서드 내에서 선언되어 사용하는 클래스이다.

· 메서드 내에서 선언되기 때문에 해당 클래스는 메서드 내에서만 사용이 가능하고,

메서드의 실행이 끝나면 클래스도 사용이 종료된다.

· 메서드 내에서만 선언하여 사용하기 때문에 접근 제한자와 정적 키워드는 붙일 수 없다.

· 생성과 선언

public class 외부클래스명 { ... public void print() { ... class 내부클래스명 { ... } 내부클래스명 객체명 = new 내부클래스명(); } }

메서드 내에서만 선언되고 사용한다.

- 익명 클래스 (anonymous class)

내부 클래스의 접근 제한

- 접근 제한자

· 내부 클래스도 클래스이기 때문에 접근 제한자를 붙여서 사용이 가능하다.

public class 외부클래스명 { // 외부 클래스 ... private class 내부클래스명 { // 내부 클래스를 private로 생성 ... public void print() { syso("접근을 private로 제한한다."); } } public 내부클래스명 getInClass() { // 인스턴스 클래스를 선언하며 리턴 return new 내부클래스명(); // 생성자 } public static void main(String[] args) { 외부클래스명 객체명 = new 외부클래스생성자; 객체명.getInClass().print(); }
접근을 private로 제한한다.

- 지역 클래스의 접근 제한

· 보통 메서드가 종료되면 클래스도 함께 종료되지만 메서드와 실행되는 위치가 다르기 때문에 종료되지 않고 남아있을 수 있다.

그래서 지역 클래스에서 메서드 내의 변수를 사용할 때는 변수를 복사해서 사용하는데, 이 이유로 지역 클래스에서 메서드 변수를 사용할 때

해당 변수가 변경되면 오류가 발생한다.

⇒ 사용하는 변수는 final(상수) 취급한다.

익명 클래스

- 이름이 없는 클래스를 의미한다.

- 클래스의 선언과 객체의 생성을 동시에 하므로 단 한 번만 사용이 가능하며, 오직 하나의 객체만을 생성할 수 있다. (일회용 클래스)

- 생성자를 선언할 수 없고, 둘 이상의 인터페이스를 구현할 수 없다.

(단 하나의 클래스를 상속받건 단 하나의 인터페이스를 구현)

- 하위 클래스를 한 번만 사용하고 더 이상 사용하지 않을 때 사용된다.

- 보통 인터페이스 기능을 구현할 때 사용되며, 인터페이스를 상속하여 하위 클래스를 통해 구현하는 것이 아닌 인터페이스를 익명 클래스로

선언하여 기능을 구현한다.

- 선언

· 클래스 생성자 뒤에 코드 블록이 추가되고, ,해당 클래스가 가진 메서드들을 override하여 구현하는 방식이다.

· 해당 클래스 자체를 재정의하여 구현한다.

· 구현된 문법 마지막에는 세미콜론(;)을 붙인다.

ex) // 부모 클래스 public class Person { public void mySelf() { syso("나는 사람입니다."); } } // 익명 클래스 생성 Person p = new Person() { @Override void method() { ... } ... };