삶 가운데 남긴 기록 AACII.TISTORY.COM
중첩 클래스 중첩 인터페이스 본문
중첩(Nested) 클래스, 인터페이스
중첩 클래스는 클래스 내부에 선언한 클래스를 말합니다.
마찬가지로 클래스 내부에 선언하는 인터페이스는 중첩 인터페이스입니다.
각 클래스간 긴밀한 관계에 있을 때, 혹은 UI 프로그램을 만들 때 이벤트를 처리할 목적으로 많이 활용됩니다.
public class View{
public interface OnClickListener{
public void onClick(View v);
}
}
인스턴스 멤버 클래스
class A{
class B{
...
}
}
외부에서 B클래스의 인스턴스 객체를 만들려면 A클래스의 인스턴스 객체를 먼저 생성하고 B클래스의 인스턴스를 생성해야 합니다.
A a = new A();
A.B b = a.new B();
만약 중첩 클래스를 static으로 선언했다면 A클래스의 인스턴스 객체를 생성할 필요가 없고, 클래스 이름으로 바로 접근할 수 있습니다.
로컬 클래스
중첩 클래스는 메서드 내부에서도 선언할 수 있는데 이때 메서드 내부의 클래스를 로컬(local) 클래스라고 합니다.
로컬 클래스는 메서드 내부에서만 사용되기 때문에, 당연하게도 접근제한자(public, private, ...) static을 붙일 수 없고 인스턴스 멤버(필드,메서드)만 선언 할 수 있습니다.
주로 비동기 처리를 위해 스레드 객체를 만들때 사용됩니다.
void method1(){
class DownThread extends Thread{ ... }
DownThread thread = new DownThread();
thread.start();
}
중첩 클래스의 접근 제한
public class A {
//인스턴스 멤버
class B {}
//static 멤버
static class C {}
B filed1 = new B();
C filed2 = new C();
void method1() {
B var1 = new B();
C var2 = new C();
}
//static B field3 = new B(); //(X)
static C filed4 = new C();
static void method2() {
//B var1 = new B(); //(X)
C var2 = new C();
}
}
멤버 클래스에서 사용 제한
public class A {
//인스턴스 필드
int field1;
void method1() { }
//static 필드
static int field2;
static void method2() {
}
class B{
void method() {
//모든 필드와 메소드에 접근할 수 있음
field1 = 10;
method1();
field2 = 11;
method2();
}
}
static class C{
void method() {
//인스턴스 필드에는 접근 할 수 없음
//field1 = 10;
//method1();
field2 = 10;
method2();
}
}
}
로컬 클래스에서 사용 제한
로컬 클래스의 객체는 메소드 실행이 끝나도 heap 메모리에 존재해서 계속 사용할 수 있지만 parameter나 로컬 변수는 메소드 실행이 끝나면 stack 메모리에서 제거 되기 때문에 문제가 생길 수 있습니다.
로컬 클래스에서는 final로 선언된 parameter와 로컬 변수만 사용합니다.
java7 이전에선 final 없이 사용하면 컴파일 에러가 났지만 java8에서부터는 final이 없어도 에러가 나지 않습니다.
로컬 클래스에서 사용된 parameter와 로컬 변수 모두 final 로 처리 하는 것입니다.
public class Outter {
//JDK7 이전
public void method1(final int arg) {
final int localVariable = 1;
//arg = 100; //final이라서 수정 불가
//localVariable = 100; //final 이라서 수정불가
class Inner{
public void method() {
int result = arg + localVariable;
}
}
}
//JDK 8 이후
public void method2(int arg) {
int localVariable = 1;
//arg = 100; //final이 생략되어도 final로 처리
//localVariable = 100; //마찬가지 final로 처리
class Inner{
public void method() {
int result = arg + localVariable;
}
}
}
}
중첩 클래스에서 바깥 클래스 참조
public class Nested {
String field = "Outer-field";
void method() {
System.out.println("Outer-method");
}
class Inner{
String field = "Nested-field";
void method() {
System.out.println("Nested-method");
}
void print() {
System.out.println(this.field); //Inner의 인스턴스이름인 this로 참조
this.method(); //Inner의 this
System.out.println(Nested.this.field); //바깥 클래스의 인스턴스 이름인 this로 참조
Nested.this.method();
}
}
}
public class NestedExample {
public static void main(String[] args) {
Nested outter = new Nested();
Nested.Inner inner = outter.new Inner();
inner.print();
}
}
중첩 인터페이스
중첩 인터페이스는 클래스의 멤버로 선언된 인터페이스를 말합니다.
주로 UI프로그래밍에서 이벤트를 처리할 목적으로 활용됩니다.
예를 들어, 이벤트를 처리하는 객체를 받을 때 중첩 인터페이스를 구현한 객체만 받도록 할 수 있습니다.
public class Button {
OnClickListener listener; //인터페이스 타입 필드
void setOnClickListener(OnClickListener listener) {
this.listener = listener;
}
void touch() {
listener.onClick(); //구현된 객체의 onClick() 메소드 호출
}
//중첩 인터페이스
interface OnClickListener{
void onClick();
}
}
public class CallListener implements Button.OnClickListener {
public void onClick() {
System.out.println("Call!");
}
}
public class MessageListener implements Button.OnClickListener{
public void onClick() {
System.out.println("Message!!");
}
}
버튼 이벤트 처리
public class ButtonExample {
public static void main(String[] args) {
Button btn = new Button();
btn.setOnClickListener(new CallListener());
btn.touch();
btn.setOnClickListener(new MessageListener());
btn.touch();
}
}
'DEV&OPS > Java' 카테고리의 다른 글
예외 처리 (0) | 2022.04.06 |
---|---|
익명 객체 (0) | 2022.04.05 |
추상 클래스와 인터페이스 (0) | 2022.03.31 |
자바 클래스와 메서드 (0) | 2022.03.28 |
조건문과 제어문 (0) | 2022.03.25 |