* 이 글은 제가 공부하기 위해 최대한 사실에 입각해 내용을 적으려고 하지만 일부 내용들이 정확하지 않을 수 있습니다.
혹시나 잘못된 부분이 있으면 너그럽게 이해해주시고 피드백 부탁드려요!
10장 내부클래스
10.1 내부클래스
내부(중첩) 클래스의 구조는 아래와 같다.
class 클래스 명 { class 내부 클래스명 { ... } } |
내부 클래스는 크게 두가지로 구분 되는데, 하나는 클래스의 멤버로 정의되는 멤버 클래스와 메서드 내부에 정의되는 로컬 클래스로 나눠진다. 멤버 클래스는 객체로 생성된 후 어디서든 다시 사용할 수 있지만, 로컬 클래스는 메서드 내에서만 사용된다. 멤버 클래스와 로컬 클래스가 정의되고 컴파일되면 실제 파일도 별도로 생성된다.
멤버 클래스의 파일명은 아래와 같다.
바깥클래스명 $내부클래스명.class |
로컬 클래스의 파일명은 아래와 같다.
바깥클래스명$1내부클래스명.class |
멤버 클래스
멤버 클래스는 static 멤버 클래스와 인스턴스 멤버 클래스로 나눠진다. static 멤버 클래스(static inner class)는 내부 클래스의 객체를 바깥 클래스에 대해 독립적으로 생성할 때 사용된다. static 키워드를 가진 내부클래스로, 멤버변수나 메서드처럼 클래스 내부에서 선언된다. 내부 클래스 내에 static 멤버가 있으면 반드시 static 내부 클래스로 선언해야 한다.
public class Outer { // Outer 클래스의 내용 ... public static class Inner { // Inner 클래스의 내용 } } |
다른 곳에서 Inner 클래스 객체를 생성하기 위해 Inner 클래스에 접근하려면, 아래와 같이 객체를 생성한다.
Outer.inner inn = new Outer.Inner(); |
인스턴스 내부 클래스
인스턴스 내부 클래스는 static 내부 클래스와 같은 위치에 선언하지만, static 키워드가 포함되지 않는다.
public class Outer { // Outer 클래스의 내용 ... public class Inner { // Inner 클래스의 내용 } } |
다른 곳에서 안쪽 클래스의 객체를 생성하기 위해서는 바깥 클래스의 객체를 먼저 생성하고, 그 객체변수를 이용해서 내부 클래스의 객체를 생성한다.
Outer outer = new Outer(); Outer.Inner inn = outer.new Inner(); |
로컬 클래스
static 내부 클래스나 인스턴스 내부 클래스는 바깥 클래스의 멤버와 같은 위치에 선언했으나, 로컬 클래스는 바깥 클래스의 메서드 내에 선언된다.
package chapter10;
public class OuterEx {
public static void main(String[] args) {
Outer outer = new Outer();
Outer.SInner sInner = new Outer.SInner();
Outer.Inner inner = new Outer().new Inner();
Outer.Inner inner2 = outer.new Inner();
System.out.println(Outer.SInner.si3);
System.out.println(sInner.i3);
System.out.println(inner.i2);
System.out.println(Outer.Inner.si2);
}
}
class Outer {
// 인스턴스 변수 : 인스턴스가 필요
// 클래스 변수 : 인스턴스가 안필요함
// 클래스 변수를 만들면 inner, Sinner 접근 가능
// 인스턴스 변수를 만들면 inner 접근 가능, sinner 접근 불가능
// iv
int i;
// cv
static int si;
class Inner {
int i2;
static int si2;
{
i = 10;
si = 20;
}
} // 인스턴스 변수가 필요함
static class SInner {
int i3;
static int si3;
{
// i = 30; // 에러생성
si = 40;
}
} // 인스턴스 변수가 안 필요함
}
package chapter10;
import java.util.HashMap;
import java.util.Map;
//import java.util.Map.Entry;
public class OuterEx {
public static void main(String[] args) {
Outer outer = new Outer();
Outer.SInner sInner = new Outer.SInner();
Outer.Inner inner = new Outer().new Inner();
Outer.Inner inner2 = outer.new Inner();
System.out.println(Outer.SInner.si3);
System.out.println(sInner.i3);
System.out.println(inner.i2);
System.out.println(Outer.Inner.si2);
Map<String, Integer> map = new HashMap<>();
map.put("A", 10);
map.put("B", 20);
System.out.println(map);
System.out.println(map.get("B"));
// for(Entry<K, V> : map) {
for(Map.Entry<String, Integer> e : map.entrySet()) { // 각각의 따로 값들을 확인 가능
System.out.println(e.getKey());
System.out.println(e.getValue());
}
}
}
class Outer {
// 인스턴스 변수 : 인스턴스가 필요
// 클래스 변수 : 인스턴스가 안필요함
// 클래스 변수를 만들면 inner, Sinner 접근 가능
// 인스턴스 변수를 만들면 inner 접근 가능, sinner 접근 불가능
// iv
int i;
// cv
static int si;
class Inner {
int i2;
static int si2;
{
i = 10;
si = 20;
}
} // 인스턴스 변수가 필요함
static class SInner {
int i3;
static int si3;
{
// i = 30; // 에러생성
si = 40;
}
} // 인스턴스 변수가 안 필요함
}
10.2 내부 인터페이스
내부 인터페이스는 클래스의 멤버로 선언된 인터페이스이다. 이 내부 인터페이스를 사용하는 이유도 속해 있는 바깥 클래스와 직접적인 관련이 있는 경우이다. (안드로이드의 이벤트 처리 인터페이스가 이런 형태로 만들어져 있는 경우가 많음)
class 클래스명 { interface 인터페이스명 { void method(); // 추상메서드 } } |
package chapter10;
public class LocalEx {
public static void main(String[] args) {
Fightable f1 = getFighter();
Fightable f2 = new Fighter();
Fightable f3 = getFighter2();
Fightable f4 = new Fightable() { // 블록안에만 익명클래스 (1)일지 (2)일지는 모름
@Override
public void fight() {
// TODO Auto-generated method stub
System.out.println("f4.fight()");
}
};
f1.fight();
f2.fight();
f3.fight();
f4.fight();
}
// 지역 클래스
static Fightable getFighter() {
class MyFighter implements Fightable {
public void fight() {
System.out.println("MyFighter.fight()");
}
}
return new MyFighter();
}
// 익명 클래스
static Fightable getFighter2() {
return new Fightable() {
public void fight() {
System.out.println("getFighter2().fight()");
}
};
}
}
interface Fightable {
void fight();
}
class Fighter implements Fightable {
@Override
public void fight() {
// TODO Auto-generated method stub
System.out.println("Fighter.fight()");
}
}
'Full Stack > JAVA' 카테고리의 다른 글
[풀스택과정] JAVA 11장 예외처리(에러를 미리 대비하자) (1) | 2023.01.25 |
---|---|
[풀스택과정] JAVA 10장 연습문제 (1) | 2023.01.24 |
[풀스택과정] JAVA 9장 연습문제 (1) | 2023.01.22 |
[풀스택과정] JAVA 9장 인터페이스 (1) | 2023.01.22 |
[풀스택과정] JAVA 8장 연습문제 (1) | 2023.01.20 |