728x90
내부 클래스
클래스 안의 클래스
내부 클래스의 장점
1. 내부 클래스에서 외부 클래스의 멤버를 쉽게 접근할 수 있음.(객체를 생성하지 않고 가능)
2. 코드의 복잡성을 줄 일 수 있음(캡슐화)
package chapter07;
class AAA{
int a = 100;
BBB bbb = new BBB();
}
class BBB{
void method() {
AAA aaa = new AAA();
System.out.println(aaa.a);
}
}
class CCC{
BBB bbb = new BBB();
}
public class Study22Ex1 {
public static void main(String[] args) {
BBB bbb = new BBB();
bbb.method();
}
}
내부 클래스로 만들기
package chapter07;
class AAA{ //AAA는 BBB의 외부 클래스
int a = 100;
BBB bbb = new BBB();
class BBB{ //BBB는 AAA의 내부 클래스
void method() {
// AAA aaa = new AAA();
// System.out.println(aaa.a);
System.out.println(a); //객체 생성없이 외부 클래스의 맴버 접근 가능
}
}
}
//class CCC{
// BBB bbb = new BBB();
//
//}
public class Study22Ex1 {
public static void main(String[] args) {
// BBB bbb = new BBB();
// bbb.method();
}
}
내부클래스의 종류와 특징
내부 클래스의 종류와 유효범위는 변수와 동일
- 인스턴스 클래스 ≒ 인스턴스 변수
- 스태틱 클래스 ≒ 클래스 변수
- 지역 클래스 ≒ 지역 변수
- 익명 클래스 : 클래스의 선언과 객체의 생성을 동시에 하는 이름없는 클래스(일회용). 이벤트처리
내부 클래스의 제어자와 접근성
package chapter07;
public class Study23Ex1 {
//인스턴스 내부클래스
class InstanceInner{
int iv = 100;
// static int cv = 100; //static 변수 선언 불가
final static int CONST = 100; //final static은 상수이므로 허용
}
//static 내부클래스
static class StaticInner{
int iv = 200;
static int cv = 200; //static 클래스만 static멤버를 정의할 수 있음
}
void method() {
//지역 내부클래스
class LocalInner{
int iv = 300;
// static int cv = 300; //static 변수 선언 불가
final static int CONST = 300; //final static은 상수이므로 허용
}
int i = LocalInner.CONST; //가능
}
public static void main(String[] args) {
System.out.println(InstanceInner.CONST);
System.out.println(StaticInner.cv);
// System.out.println(LocalInner.CONST); //에러. 지역 내부클래스는 메서드 내에서만
}
}
package chapter07;
public class Study23Ex2 {
class InstanceInner{}
static class StaticInner{}
InstanceInner iv = new InstanceInner(); //인스턴스 멤버끼리는 직접 접근가능
static StaticInner cv = new StaticInner(); //static 멤버끼리는 직접 접근 가능
static void staticMethod() { //static멤버는 인스턴스 멤버에 직접 접근 불가
// InstanceInner obj1 = new StaticInner();
StaticInner obj2 = new StaticInner();
}
void instanceMethod(){ //인스턴스 메서드에서는 인스턴스 멤버와 static멤버 모두 접근 가능
InstanceInner obj1 = new InstanceInner();
StaticInner obj2 = new StaticInner();
// LocalInner iv = new LocalInner(); //지역 내부 클래스는 외부에서 접근할 수 없음
}
void method() {
class LocalInner{}
LocalInner lv = new LocalInner();
}
}
package chapter07;
class Outer{
private int outerIv = 0;
static int outerCv = 0;
class InstanceInner{
int iiv = outerIv; //외부 클래스의 private 멤버도 가능(같은 클래스 안)
int iiv2 = outerCv;
}
static class StaticInner{
// int siv = outerIv; //static 클래스는 외부 클래스의 인스턴스 멤버에 접근할 수 없음
static int scv = outerCv;
}
void method() {
int lv = 0; //값이 바뀌지 않는 변수는 상수로 간주
final int LV = 0; //JDK1.8부터 final 생략 가능
class LocalInner{ //지역 내부 클래스를 감싸고 있는 메서드의 상수만 사용 가능
int liv = outerIv;
int liv2 = outerCv;
//외부 클래스의 지역변수는 final이 붙은 변수(상수)만 접근 가능
int liv3 = lv; //JDK 1.8부터 에러 X
int liv4 = LV;
}
}
}
public class Study23Ex3 {
}
package chapter07;
class OuterS23E4{
class InstanceInner{
int iv = 100;
}
static class StaticInner{
int iv = 200;
static int cv = 300;
}
void method() {
class LocalInner{
int iv = 400;
}
}
}
public class Study23Ex4 {
public static void main(String[] args) {
//1. 외부 클래스의 인스턴스를 생성
//2. 내부 클래스의 객체 생성
OuterS23E4 oc = new OuterS23E4();
OuterS23E4.InstanceInner ii = oc.new InstanceInner(); //인스턴스를 생성 가능
//외부 클래스의 객체 생성 없이 사용가능
System.out.println("ii.iv : " + ii.iv);
System.out.println("OuterS23E4.StaticInner.cv : " + OuterS23E4.StaticInner.cv);
//static 내부 클래스의 인스턴스는 외부 클래스를 먼저 생성하지 않아도 됨
OuterS23E4.StaticInner si = new OuterS23E4.StaticInner();
System.out.println("si.iv : " + si.iv);
}
}
package chapter07;
class OuterS23E5{
int value = 10; //OuterS23E5.this.value. 외부클래스의 iv
class Inner{
int value = 20; //this.value. 내부클래스 iv
void method1() {
int value = 30; //lv
System.out.println("value : " + value);
System.out.println("this.value : " + this.value);
System.out.println("OuterS23E5.this.value : " + OuterS23E5.this.value);
}
}
}
public class Study23Ex5 {
public static void main(String[] args) {
OuterS23E5 outer = new OuterS23E5();
OuterS23E5.Inner inner = outer.new Inner();
inner.method1();
}
}
익명 클래스
이름이 없는 일회용 클래스. 정의와 생성을 동시에
package chapter07;
public class Study24Ex1 {
Object ivObject = new Object() {
void method() {} //클래스 내용
};
static Object cvObject = new Object() {
void method() {}
};
}
package chapter07;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.EventHandler;
class EventHandler implements ActionListener{
public void actionPerformed(ActionEvent e) {
System.out.println("ActionEvent occurred");
}
}
public class Study24Ex2 {
public static void main(String[] args) {
Button b = new Button("Start");
b.addActionListener(new EventHandler());
}
}
//===================================================================================
//위의 코드를 익명 클래스로 변경
public class Study24Ex2 {
public static void main(String[] args) {
Button b = new Button("Start");
b.addActionListener(new ActionListener() { //클래스의 정의와 객체 생성을 동시에
public void actionPerformed(ActionEvent e) {
System.out.println("ActionEvent occurred");
}
});
}
}
728x90