[Java] λ΄λΆ ν΄λμ€(inner class) μ μ΅λͺ ν΄λμ€(anonymous class)
μλ‘
λλ€μμ λν΄μ νμ΅νλ€κ° μ΅λͺ κ°μ²΄λΌλ μ©μ΄κ° μμ£Ό λμκ³ , μ΅λͺ κ°μ²΄λ₯Ό νμ΅νλ€ λ³΄λ μ΅μ’ μ μΌλ‘ inner classμ λλ¬νκ² λμμ΅λλ€.
λ΄λΆ ν΄λμ€(inner class)λ μ¬μ€ ν΄λμ€ λ΄μ μ μΈλλ€λ μ μ μ μΈνκ³ λ μΌλ°μ μΈ ν΄λμ€μ λ€λ₯΄μ§ μμ΅λλ€. λ΄λΆ ν΄λμ€μλ μΈμ€ν΄μ€ ν΄λμ€, μ€νν± ν΄λμ€, μ§μ ν΄λμ€, μ΅λͺ ν΄λμ€μ μ’ λ₯λ‘ λλ μ μλλ° νλ² μμΈνκ² μ λ¦¬ν΄ λ³΄κ² μ΅λλ€.
λͺ©μ°¨
1. λ΄λΆ ν΄λμ€λ?
2. λ΄λΆ ν΄λμ€μ μ’ λ₯μ νΉμ§
3. λ΄λΆ ν΄λμ€μ μ μΈ
4. λ΄λΆ ν΄λμ€μ μ μ΄μ μ κ·Όμ±
5. μ΅λͺ ν΄λμ€(anonymous class)
1. λ΄λΆ ν΄λμ€λ?
λ΄λΆ ν΄λμ€λ ν΄λμ€ λ΄μ μ μΈλ ν΄λμ€μ λλ€. ν ν΄λμ€λ₯Ό λ€λ₯Έ ν΄λμ€μ λ΄λΆ ν΄λμ€λ‘ μ μΈνλ©΄ λ ν΄λμ€μ λ©€λ²λ€ κ°μ μλ‘ μ½κ² μ κ·Όν μ μλ€λ μ₯μ κ³Ό μΈλΆμλ λΆνμν ν΄λμ€λ₯Ό κ°μΆ€μΌλ‘μ¨ μ½λμ 볡μ‘μ±μ μ€μΌ μ μλ€λ μ₯μ μ μ»μ μ μμ΅λλ€.
λ΄λΆ ν΄λμ€μ μ₯μ
- λ΄λΆ ν΄λμ€μμ μΈλΆ ν΄λμ€μ λ©€λ²λ€μ μ½κ² μ κ·Όν μ μλ€.
- μ½λμ 볡μ‘μ±μ μ€μΌ μ μλ€(μΊ‘μν).
νμ¬ Aμ B λκ°μ λ 립μ μΈ ν΄λμ€λ₯Ό κ°μ§κ³ μλ μΌμͺ½ μ΄λ―Έμ§λ₯Ό μ€λ₯Έμͺ½κ³Ό κ°μ΄ λ°κΎΈλ©΄ Bλ Aμ λ΄λΆ ν΄λμ€(inner class)κ° λκ³ Aλ Bλ₯Ό κ°μΈκ³ μλ μΈλΆ ν΄λμ€(outer class)κ° λ©λλ€.
μ΄λ λ΄λΆ ν΄λμ€μΈ Bλ μΈλΆ ν΄λμ€μΈ Aλ₯Ό μ μΈνκ³ λ λ€λ₯Έ ν΄λμ€μμ μ μ¬μ©λμ§ μμμΌ ν©λλ€.
2. λ΄λΆ ν΄λμ€μ μ’ λ₯μ νΉμ§
λ΄λΆ ν΄λμ€μ μ’ λ₯λ λ³μμ μ μΈ μμΉμ λ°λ₯Έ μ’ λ₯μ κ°μ΅λλ€. λ΄λΆ ν΄λμ€λ λ§μΉ λ³μλ₯Ό μ μΈνλ κ²κ³Ό κ°μ μμΉμ μ μΈν μ μμΌλ©°, λ³μμ μ μΈ μμΉμ λ°λΌ μΈμ€ν΄μ€ λ³μ, ν΄λμ€ λ³μ(static λ³μ), μ§μλ³μλ‘ κ΅¬λΆλλ κ²κ³Ό κ°μ΄ λ΄λΆ ν΄λμ€λ μ μΈ μμΉμ λ°λΌ λ€μκ³Ό κ°μ΄ ꡬλΆλμ΄μ§λλ€.
λ΄λΆ ν΄λμ€ | νΉ μ§ |
μΈμ€ν΄μ€ ν΄λμ€(instance class) | μΈλΆ ν΄λμ€μ λ©€λ²λ³μ μ μΈμμΉμ μ μΈνλ©°, μΈλΆ ν΄λμ€μ μΈμ€ν΄μ€λ©€λ²μ²λΌ λ€λ£¨μ΄μ§λ€. μ£Όλ‘ μΈλΆ ν΄λμ€μ μΈμ€ν΄μ€λ©€λ²λ€κ³Ό κ΄λ ¨λ μμ μ μ¬μ©λ λͺ©μ μΌλ‘ μ μΈλλ€. |
μ€νν± ν΄λμ€(static class) | μΈλΆ ν΄λμ€μ λ©€λ²λ³μ μ μΈμμΉμ μ μΈνλ©°, μΈλΆ ν΄λμ€μ staticλ©€λ²μ²λΌ λ€λ£¨μ΄μ§λ€. μ£Όλ‘ μΈλΆ ν΄λμ€μ staticλ©€λ², νΉν staticλ©μλμμ μ¬μ©λ λͺ©μ μΌλ‘ μ μΈλλ€. |
μ§μ ν΄λμ€(local class) | μΈλΆ ν΄λμ€μ λ©μλλ μ΄κΈ°νλΈλ μμ μ μΈνλ©°, μ μΈλ μμ λ΄λΆμμλ§ μ¬μ©λ μ μλ€. |
μ΅λͺ ν΄λμ€(anonymous class) | ν΄λμ€μ μ μΈκ³Ό κ°μ²΄μ μμ±μ λμμ νλ μ΄λ¦μλ ν΄λμ€(μΌνμ©) |
3. λ΄λΆ ν΄λμ€μ μ μΈ
μ μ€λ₯Έμͺ½ μ½λμλ μΈλΆ ν΄λμ€(Outer)μ 3κ°μ μλ‘ λ€λ₯Έ μ’ λ₯μ λ΄λΆ ν΄λμ€κ° μ μΈλμ΄ μμ΅λλ€. μμͺ½μ μ½λλ₯Ό λΉκ΅ν΄ 보면 λ΄λΆ ν΄λμ€μ μ μΈ μμΉκ° λ³μμ μ μΈ μμΉμ λμΌν κ²μ λ³Ό μ μμ΅λλ€.
λ³μκ° μ μΈλ μμΉμ λ°λΌ μΈμ€ν΄μ€ λ³μ, ν΄λμ€ λ³μ(staticλ³μ), μ§μλ³μλ‘ λλλ―μ΄ λ΄λΆ ν΄λμ€λ μ΄μ λ§μ°¬κ°μ§λ‘ μ μΈλ μμΉμ λ°λΌ λλ©λλ€. κ·Έλ¦¬κ³ , κ° λ΄λΆ ν΄λμ€μ μ μΈ μμΉμ λ°λΌ κ°μ μ μΈ μμΉμ λ³μμ λμΌν μ ν¨ λ²μ(scope)μ μ κ·Όμ±(accessibility)μ κ°μ΅λλ€.
4. λ΄λΆ ν΄λμ€μ μ μ΄μμ μ κ·Όμ±
μ μ½λμμ μΈμ€ν΄μ€ ν΄λμ€(instance class)μ μ€νν± ν΄λμ€(static inner)λ μΈλΆ ν΄λμ€(Outer)μ λ©€λ² λ³μ(μΈμ€ν΄μ€ λ³μμ ν΄λμ€ λ³μ)μ κ°μ μμΉμ μ μΈλλ©°, λν λ©€λ² λ³μμ κ°μ μ±μ§μ κ°μ΅λλ€. λ°λΌμ λ΄λΆ ν΄λμ€κ° μΈλΆ ν΄λμ€μ λ©€λ²μ κ°μ΄ κ°μ£Όλκ³ , μΈμ€ν΄μ€ λ©€λ²μ staticλ©€λ² κ°μ κ·μΉμ΄ λ΄λΆ ν΄λμ€μλ λκ°μ΄ μ μ©λ©λλ€.
κ·Έλ¦¬κ³ λ΄λΆ ν΄λμ€λ ν΄λμ€μ΄κΈ° λλ¬Έμ abstractλ finalκ³Ό κ°μ μ μ΄μλ₯Ό μ¬μ©ν μ μμ λΏλ§ μλλΌ, λ©€λ² λ³μλ€μ²λΌ private, protectedμ μ κ·Όμ μ΄μλ μ¬μ©μ΄ κ°λ₯ν©λλ€.
μμ 1)
class InnerEx1 {
class InstanceInner {
int iv = 100;
// static int cv = 100; // μλ¬! staticλ³μλ₯Ό μ μΈν μ μλ€.
final static int CONST = 100; // final staticμ μμμ΄λ―λ‘ νμ©νλ€.
}
static class StaticInner {
int iv = 200;
static int cv = 200; // staticν΄λμ€λ§ staticλ©€λ²λ₯Ό μ μν μ μλ€.
}
void myMethod() {
class LocalInner {
int iv = 300;
// static int cv = 300; // μλ¬! staticλ³μλ₯Ό μ μΈν μ μλ€.
final static int CONST = 300; // final staticμ μμμ΄λ―λ‘ νμ©
}
}
public static void main(String args[]) {
System.out.println(InstanceInner.CONST); //100
System.out.println(StaticInner.cv); //200
}
}
μ μ½λλ₯Ό 보면 λ΄λΆ ν΄λμ€ μ€μμ μ€νν± ν΄λμ€(static inner)λ§ static λ©€λ²λ₯Ό κ°μ§ μ μμ΅λλ€. λλ¬Έ κ²½μ°μ§λ§ λ΄λΆ ν΄λμ€μ staticλ³μλ₯Ό μ μΈν΄μΌ νλ€λ©΄ μ€νν± ν΄λμ€(static class)λ‘ μ μΈν΄μΌ ν©λλ€.
λ€λ§ finalκ³Ό staticμ΄ λμμ λΆμ μμ(constant)λ λͺ¨λ λ΄λΆ ν΄λμ€μμ μ μκ° κ°λ₯ν©λλ€.
μμ 2)
class InnerEx2 {
class InstanceInner {}
static class StaticInner {}
// μΈμ€ν΄μ€λ©€λ² κ°μλ μλ‘ μ§μ μ κ·Όμ΄ κ°λ₯νλ€.
InstanceInner iv = new InstanceInner();
// static λ©€λ² κ°μλ μλ‘ μ§μ μ κ·Όμ΄ κ°λ₯νλ€.
static StaticInner cv = new StaticInner();
static void staticMethod() {
// staticλ©€λ²λ μΈμ€ν΄μ€λ©€λ²μ μ§μ μ κ·Όν μ μλ€.
// InstanceInner obj1 = new InstanceInner();
StaticInner obj2 = new StaticInner();
// κ΅³μ΄ μ κ·Όνλ €λ©΄ μλμ κ°μ΄ κ°μ²΄λ₯Ό μμ±ν΄μΌ νλ€.
// μΈμ€ν΄μ€ν΄λμ€λ μΈλΆ ν΄λμ€λ₯Ό λ¨Όμ μμ±ν΄μΌλ§ μμ±ν μ μλ€.
InnerEx2 outer = new InnerEx2();
InstanceInner obj1 = outer.new InstanceInner();
}
void instanceMethod() {
// μΈμ€ν΄μ€λ©μλμμλ μΈμ€ν΄μ€λ©€λ²μ staticλ©€λ² λͺ¨λ μ κ·Ό κ°λ₯νλ€.
InstanceInner obj1 = new InstanceInner();
StaticInner obj2 = new StaticInner();
// λ©μλ λ΄μ μ§μμ μΌλ‘ μ μΈλ λ΄λΆ ν΄λμ€λ μΈλΆμμ μ κ·Όν μ μλ€.
// LocalInner lv = new LocalInner();
}
void myMethod() {
class LocalInner {}
LocalInner lv = new LocalInner();
}
}
μ μ½λλ₯Ό μ 리νλ©΄ μλμ κ°μ΅λλ€.
- μΈμ€ν΄μ€ λ©€λ²λ κ°μ ν΄λμ€μ μλ μΈμ€ν΄μ€ λ©€λ²μ static λ©€λ² λͺ¨λ μ§μ νΈμΆμ΄ κ°λ₯νμ§λ§, static λ©€λ²λ μΈμ€ν΄μ€ λ©€λ²λ₯Ό μ§μ νΈμΆν μ μμ΅λλ€.
- λν μΈμ€ν΄μ€ ν΄λμ€λ μΈλΆ ν΄λμ€μ μΈμ€ν΄μ€ λ©€λ²λ₯Ό κ°μ²΄ μμ± μμ΄ λ°λ‘ μ¬μ©ν μ μμ§λ§, μ€νν± ν΄λμ€λ μΈλΆ ν΄λμ€μ μΈμ€ν΄μ€ λ©€λ²λ₯Ό κ°μ²΄μμ± μμ΄ μ¬μ©ν μ μμ΅λλ€.
- λ§μ°¬κ°μ§λ‘ μΈμ€ν΄μ€ ν΄λμ€λ μ€νν± ν΄λμ€μ λ©€λ²λ€μ κ°μ²΄ μμ± μμ΄ μ¬μ©ν μ μμ§λ§, μ€νν± ν΄λμ€μμλ μΈμ€ν΄μ€ ν΄λμ€μ λ©€λ²λ€μ κ°μ²΄μμ± μμ΄ μ¬μ©ν μ μμ΅λλ€.
μμ 3)
class InnerEx3 {
private int outerIv = 0;
static int outerCv = 0;
class InstanceInner {
int iiv = outerIv; // μΈλΆ ν΄λμ€μ privateλ©€λ²λ μ κ·Όκ°λ₯νλ€.
int iiv2 = outerCv;
}
static class StaticInner {
// μ€νν± ν΄λμ€λ μΈλΆ ν΄λμ€μ μΈμ€ν΄μ€λ©€λ²μ μ κ·Όν μ μλ€.
// int siv = outerIv;
static int scv = outerCv;
}
void myMethod() {
int lv = 0;
final int LV = 0; // JDK1.8λΆν° final μλ΅ κ°λ₯
class LocalInner {
int liv = outerIv;
int liv2 = outerCv;
// μΈλΆ ν΄λμ€μ μ§μλ³μλ finalμ΄ λΆμ λ³μ(μμ)λ§ μ κ·Όκ°λ₯νλ€.
// int liv3 = lv; // μλ¬!!!(JDK1.8λΆν° μλ¬ μλ)
int liv4 = LV; // OK
}
}
}
λ΄λΆ ν΄λμ€μμ μΈλΆ ν΄λμ€μ λ³μλ€μ λν μ κ·Όμ±μ λ³΄μ¬ μ£Όλ μμ μ λλ€. μΈμ€ν΄μ€ ν΄λμ€(instance class)λ μΈλΆ ν΄λμ€(InnerEx3)μ μΈμ€ν΄μ€ λ©€λ²μ΄κΈ° λλ¬Έμ μΈμ€ν΄μ€ λ³μ outerIvμ static λ³μ outerCvλ₯Ό λͺ¨λ μ¬μ©ν μ μμ΅λλ€. μ¬μ§μ΄λ outerIvμ μ κ·Ό μ μ΄μκ° privateμΌμ§λΌλ μ¬μ© κ°λ₯ν©λλ€.
μ€νν± ν΄λμ€(static inner)λ μΈλΆ ν΄λμ€(InnerEx3)μ staticλ©€λ²μ΄κΈ° λλ¬Έμ μΈλΆ ν΄λμ€μ μΈμ€ν΄μ€ λ©€λ²μΈ outerIvμ instanceInnerλ₯Ό μ¬μ©ν μ μμ΅λλ€. λ¨μ§ static λ©€λ²μΈ iouterCvλ§μ μ¬μ©ν μ μμ΅λλ€.
μ§μ ν΄λμ€(LocalInner)λ μΈλΆ ν΄λμ€μ μΈμ€ν΄μ€ λ©€λ²μ static λ©€λ²λ₯Ό λͺ¨λ μ¬μ©ν μ μμΌλ©°, μ§μ ν΄λμ€κ° ν¬ν¨λ λ©μλμ μ μλ μ§μλ³μλ μ¬μ©ν μ μμ΅λλ€. λ¨ finalμ΄ λΆμ μ§μ λ³μλ§ μ κ·Όμ΄ κ°λ₯νλ°, κ·Έ μ΄μ λ λ©μλκ° μνμ λ§μ³μ μ§μλ³μκ° μλ©Έλ μμ μλ, μ§μ ν΄λμ€μ μΈμ€ν΄μ€κ° μλ©Έλ μ§μλ³μλ₯Ό μ°Έμ‘°νλ €λ κ²½μ°κ° λ°μν μ μκΈ° λλ¬Έμ λλ€.
JDK1.8λΆν° μ§μ ν΄λμ€μμ μ κ·Όνλ μ§μ λ³μ μμ finalμ μλ΅ν μ μκ² λ°λμμ΅λλ€. μ»΄νμΌλ¬κ° μλμΌλ‘ finalμ λΆμ¬μ£Όλ©°, finalμ΄κΈ° λλ¬Έμ ν΄λΉ λ³μμ κ°μ΄ λ°λλ λ¬Έμ₯μ΄ μμΌλ©΄ μ»΄νμΌ μλ¬κ° λ°μν©λλ€.
5. μ΅λͺ ν΄λμ€(anonymous class)
μ΄μ μ € μ²μ μκ³ μΆμλ μ΅λͺ ν΄λμ€μ λν΄ μμλ³΄κ² μ΅λλ€.
μ΅λͺ ν΄λμ€λ νΉμ΄νκ²λ λ€λ₯Έ λ΄λΆ ν΄λμ€λ€κ³Όλ λ¬λ¦¬ μ΄λ¦μ΄ μμ΅λλ€. μ¦, ν΄λμ€μ μ μΈκ³Ό κ°μ²΄μ μμ±μ λμμ νκΈ° λλ¬Έμ λ¨ ν λ²λ§ μ¬μ©λ μ μκ³ μ€μ§ λ¨ νλμ κ°μ²΄λ§μ μμ±ν μ μλ μΌνμ© ν΄λμ€μ λλ€.
μ΄λ¦μ΄ μκΈ° λλ¬Έμ μμ±μλ κ°μ§ μ μμΌλ©°, μ‘°μ ν΄λμ€μ μ΄λ¦μ΄λ ꡬννκ³ μ νλ μΈν°νμ΄μ€μ μ΄λ¦μ μ¬μ©ν΄μ μ μνκΈ° λλ¬Έμ νλμ ν΄λμ€λ‘ μμλ°λ λμμ μΈν°νμ΄μ€λ₯Ό ꡬννκ±°λ λ μ΄μμ μΈν°νμ΄μ€λ₯Ό ꡬνν μ μμ΅λλ€.
μ€λ‘μ§ λ¨ νλμ ν΄λμ€λ₯Ό μμλ°κ±°λ λ¨ νλμ μΈν°νμ΄μ€λ§μ ꡬνν μ μμ΅λλ€.
class InnerEx6 {
Object iv = new Object(){ void method(){} }; // μ΅λͺ
ν΄λμ€
static Object cv = new Object(){ void method(){} }; // μ΅λͺ
ν΄λμ€
void myMethod() {
Object lv = new Object(){ void method(){} }; // μ΅λͺ
ν΄λμ€
}
}
μμ μμ λ λ¨μν μ΅λͺ ν΄λμ€μ μ¬μ© μλ₯Ό λ³΄μ¬ μ€ κ²μ λλ€. μ΄μ μ΄ μμ λ₯Ό μ»΄νμΌνλ©΄ λ€μκ³Ό κ°μ΄ 4κ°μ ν΄λμ€ νμΌμ΄ μμ±λ©λλ€.
μ΅λͺ ν΄λμ€λ μ΄λ¦μ΄ μκΈ° λλ¬Έμ 'μΈλΆ ν΄λμ€λͺ $μ«μ.class'μ νμμΌλ‘ ν΄λμ€ νμΌλͺ μ΄ κ²°μ λ©λλ€.
class Child extends Parent {
}
ParentλΌλ λΆλͺ¨ ν΄λμ€μ, μ΄λ₯Ό μμλ°μ ChildλΌλ μμ ν΄λμ€κ° μλ€κ³ κ°μ ν΄λ³΄κ² μ΅λλ€.
Parent field = new Child();
μ΄λ₯Ό μμ κ°μ΄ μ¬μ©ν μ μμ΅λλ€. μ΄λ μμ ν΄λμ€κ° μ¬μ¬μ©λμ§ μκ³ , μ€λ‘μ§ μ΄κΈ°κ°μΌλ‘λ§ μ¬μ©νλ κ²½μ° μ΅λͺ μμ κ°μ²΄λ₯Ό μμ±ν΄μ μ¬μ©νλ κ²μ΄ μ’μ λ°©λ²μ λλ€.
μ΅λͺ μμ κ°μ²΄ μμ± λ°©λ²μ λ€μκ³Ό κ°μ΅λλ€.
Parent field = new Parent() {
int childField;
void childMethod() {}
@Override
void parentMethod() {
childField = 3;
childMethod();
}
}
μ¦, child κ°μ μμ ν ν΄λμ€λ₯Ό μμ±νλ κ² λμ μ²μ μ§μ ν κ°μΌλ‘λ§ μ¬μ©ν μ΅λͺ κ°μ²΄λ₯Ό λ§λλ κ²μ λλ€.
- μΈλΆμμλ μ΄ μ΅λͺ κ°μ²΄μ νλμ λ©μλμ μ κ·Όν μ μλ€.
- μμ μμ μ½λμ κ²½μ°, childMethod()λ ν΄λΉ μμ κ°μ²΄ λ΄λΆμμλ§ μ κ·Όμ΄ κ°λ₯νλ€.
- parentMethod()λ μ κ·Ό κ°λ₯νκ³ override ν κ²°κ³Όκ° λ°μλλ€.
- Parentκ° classμΌ μλ InterfaceμΌ μλ μλ€.
맀κ°λ³μλ‘ λΆλͺ¨ ν΄λμ€λ₯Ό λ°μμ€λ κ²½μ°λ λ€μκ³Ό κ°μ΄ μ¬μ©ν μ μμ΅λλ€.
class A {
void method1(Parent p) {}
void method2(int param){
int var2 =3;
//method1() νΈμΆ
method1(
new Parent(){
@Override
void parentMethod() {}
}
)
}
}
μ΅λͺ κ°μ²΄μ λ‘컬 λ³μ μ¬μ©
- μ΅λͺ κ°μ²΄ λ΄λΆμμλ μΈλΆ ν΄λμ€μ νλλ λ©μλλ₯Ό μ ν μμ΄ μ¬μ©ν μ μλ€.
- νμ§λ§ λ©μλμ λ§€κ° λ³μ(param)λ λ‘컬 λ³μ(var2)λ₯Ό μ΅λͺ κ°μ²΄μμ μ¬μ©ν λ λ¬Έμ κ° μκΈΈ μ μλ€.
- λ©μλ λ΄μμ μμ±λ μ΅λͺ κ°μ²΄λ λ©μλ μ€νμ΄ λλλ ν λ©λͺ¨λ¦¬μ μ‘΄μ¬ν΄μ κ³μ μ¬μ©ν μ μλ€.
- νμ§λ§ λ§€κ° λ³μλ λ‘컬 λ³μλ λ©μλ μ€νμ΄ λλλ©΄ μ€ν λ©λͺ¨λ¦¬μμ μ¬λΌμ§κΈ° λλ¬Έμ μ΅λͺ κ°μ²΄μμ μ¬μ©ν μ μκ² λλ―λ‘ λ¬Έμ κ° λ°μνλ€.
- μ΄λ¬ν λ¬Έμ λ₯Ό ν΄κ²°νκΈ° μν΄μ Java 8 μ΄νλΆν°λ, μ΅λͺ κ°μ²΄ λ΄λΆμμ λ©μλ λ§€κ° λ³μλ λ‘컬 λ³μλ₯Ό μ¬μ©ν κ²½μ°, μλμΌλ‘ μ΄ λ³μλ€μ final νΉμ±μ κ°μ§κ² λλ€.