티스토리 뷰
내부 클래스
내부 클래스(Inner Class)는 클래스의 멤버 중 하나로서, 클래스 내에 선언된 클래스이다.
내부 클래스는 객체지향의 핵심 원칙인 캡슐화(encapsulation)를 달성하는 데 유용하며,
코드의 복잡성을 효과적으로 줄일 수 있다.
내부 클래스는 클래스 영역에 선언된 변수와 마찬가지로 세 가지 종류로 나뉘는데,
변수와 비교해 예를 들면 다음과 같다.
class Example { // => 클래스 영역
int instanceVariable; // 인스턴스 변수
static int classVariable; // 클래스 변수(static 변수, 공유변수)
void method() { // => 메서드 영역
int localVariable = 0; // 지역 변수({}블록 안에서만 유효)
}
}
class Outer { // 외부 클래스
class Inner {
// 인스턴스 내부 클래스
}
static class StaticInner {
// 정적 내부 클래스
}
void run() {
class LocalInner {
// 지역 내부 클래스
}
}
}
변수의 경우와 마찬가지로 내부 클래스의 종류도 인스턴스 내부 클래스, 정적 내부 클래스, 지역 내부 클래스로 나뉘는 것을 볼 수 있다.
또한 선언 위치에 따라 인스턴스 내부 클래스와 정적 내부 클래스를 묶어 멤버 내부 클래스라고 부르며,
다시 static 키워드의 유무에 따라 인스턴스 내부 클래스와 정적 내부 클래스를 구분한다.
기본적으로 내부 클래스는 선언 위치를 제외하면 일반 클래스와 차이가 없으며,
각 내부 클래스의 특징은 다음과 같다.
익명 내부 클래스는 우선순위가 낮기 때문에 생략한다.
이어서 각 내부 클래스에 대해 살펴보겠다.
인스턴스 내부 클래스
인스턴스 내부 클래스는 앞서 언급한 바와 같이 멤버 내부 클래스중 하나이며,
클래스의 내부에 멤버의 형태로 존재한다.
또한 위에 올린 표와 같이 모든 변수에 접근할 수 있는데, 그 예를 들면 다음과 같다.
class Outer { //외부 클래스
private int num = 1; //외부 클래스 인스턴스 변수
private static int sNum = 2; // 외부 클래스 정적 변수
private InClass inClass; // 내부 클래스 자료형 변수 선언
public Outer() {
inClass = new InClass(); //외부 클래스 생성자
}
class InClass { //인스턴스 내부 클래스
int inNum = 10; //내부 클래스의 인스턴스 변수
void Test() {
System.out.println("Outer num = " + num + "(외부 클래스의 인스턴스 변수)");
System.out.println("Outer sNum = " + sNum + "(외부 클래스의 정적 변수)");
}
}
public void testClass() {
inClass.Test();
}
}
public class Main {
public static void main(String[] args) {
Outer outer = new Outer();
System.out.println("외부 클래스 사용하여 내부 클래스 기능 호출");
outer.testClass(); // 내부 클래스 기능 호출
}
}
// 출력 결과
외부 클래스 사용하여 내부 클래스 기능 호출
Outer num = 1(외부 클래스의 인스턴스 변수)
Outer sNum = 2(외부 클래스의 정적 변수)
코드가 초심자인 내 눈엔 조금 복잡해서 이해하기 어려웠다.
천천히 뜯어보면 외부 클래스의 안에 위치한 인스턴스 내부 클래스는 private 접근 제어자를 사용하는
외부 클래스의 변수에 접근하여 사용하고 있다는 것을 볼 수 있다.
유의할 사항은 위에서 보인 것처럼 인스턴스 내부 클래스는 반드시 외부 클래스를 생성한 이후에 사용해야 한다는 점이며,
이에 따라 정적 변수와 정적 메서드는 인스턴스 내부 클래스에서는 선언할 수 없다.
정적 내부 클래스
정적 내부 클래스 역시 멤버 내부 클래스 중 하나이다.
static키워드를 사용한다는 점이 인스턴스 내부 변수와의 차이점이며,
외부 클래스의 존재와 무관하게 정적 변수를 사용할 수 있다는 점도 큰 차이라고 할 수 있다.
class Outer { //외부 클래스
private int num = 3; //내부 클래스의 인스턴스 변수
private static int sNum = 4;
void getPrint() {
System.out.println("인스턴스 메서드");
}
static void getPrintStatic() {
System.out.println("스태틱 메서드");
}
static class StaticInClass { // 정적 내부 클래스
void test() {
System.out.println("Outer num = " +sNum + "(외부 클래스의 정적 변수)");
getPrintStatic();
// num 과 getPrint() 는 정적 멤버가 아니라 사용 불가.
}
}
}
public class Main {
public static void main(String[] args) {
Outer.StaticInClass a = new Outer.StaticInClass(); //정적 이너 클래스의 객체 생성
a.test();
}
}
//출력 결과
Outer num = 4(외부 클래스의 정적 변수)
스태틱 메서드
정적 내부 클래스는 외부 인스턴스 변수에는 접근이 불가능하며,
static 키워드가 붙은 변수와 메서드에 접근해 사용하는 것을 알 수 있다.
또한 외부 클래스가 없이도 바로 내부 클래스에 접근해 객체를 생성하고 호출해 사용할 수 있다는 특징도 확인할 수 있다.
지역 내부 클래스
지역 내부 클래스는 지역 변수의 경우와 마찬가지로 외부 클래스의 메서드 안에 선언된 클래스를 뜻한다.
지역 변수와 마찬가지로 메서드 내에서만 사용 가능하기 때문에, 메서드 안에서 선언 후 바로 객체를 생성해 사용한다.
class Outer { //외부 클래스
int num = 5;
void test() {
int num2 = 6;
class LocalInClass { //지역 내부 클래스
void getPrint() {
System.out.println(num);
System.out.println(num2);
}
}
LocalInClass localInClass = new LocalInClass();
localInClass.getPrint();
}
}
public class Main {
public static void main(String[] args) {
Outer outer = new Outer();
outer.test();
}
}
//출력 결과
5
6
test 메서드 안에 LocalInClass 클래스가 선언된 것을 볼 수 있다.
또한 위에 설명한 바와 같이 메서드 안에서 객체를 생성 후 사용하고 있다.
설명에 따르면, 내부 클래스는 개발자의 편의를 위해 서로 연관있는 클래스를 연결시켜 준 것이라고 한다.
코드를 보고 적어보는 동안에는 이해가 됐지만, 아무래도 머리에 다 들어오지 않는 느낌이 들어서 어려웠다.
'Java+Spring > Java' 카테고리의 다른 글
[Java]super vs. super() (0) | 2022.07.13 |
---|---|
[Java]메서드 오버라이딩(Method Overriding) (0) | 2022.07.13 |
[Java]상속(Inheritance), 포함 관계(Composite) (0) | 2022.07.13 |
[Java]this() vs. this (0) | 2022.07.13 |
[Java]기본 생성자 vs. 매개변수가 있는 생성자 (0) | 2022.07.13 |
[Java]생성자(Constructor) (0) | 2022.07.13 |
- Total
- Today
- Yesterday
- a6000
- 스트림
- 중남미
- 여행
- 자바
- 야경
- 남미
- 칼이사
- 기술면접
- 알고리즘
- 동적계획법
- 백준
- 유럽여행
- 유럽
- 리스트
- 파이썬
- java
- Backjoon
- Python
- spring
- 세계여행
- 스프링
- 세모
- 맛집
- Algorithm
- 지지
- RX100M5
- BOJ
- 면접 준비
- 세계일주
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |