object 예약어는 익명 클래스를 정의할 때 사용한다. 클래스 선언 때 class 예약어를 작성하지 않고 object { } 형태로 선언한다. 이렇게 선언한 object클래스는 클래스명이 없지만 선언과 동 시 에객체가 생성된다.
// object 클래스
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | class Test { private var _no: Int = 0; val myObjInner = object { val name: String = "test"; fun innerFun() { println("myObjInner -> innerFun"); _no ++; } } fun outerFun() { println("myObjInner name : ${myObjInner.name}"); // 에러 발생 myObjInner.innerFun(); // 에러 발생 } } val obj: Test = Test(); obj.outerFun(); | cs |
|
object클래스의 맴버를 외부에서 접근할 때는 object클래스 선언때 private접근자를 추가해야 한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | class Test { private var _no: Int = 0; private val myObjInner = object { val name: String = "test"; fun innerFun() { println("myObjInner -> innerFun"); _no ++; } } fun outerFun() { println("myObjInner name : ${myObjInner.name}"); myObjInner.innerFun(); } } val obj: Test = Test(); obj.outerFun(); | cs |
실행결과 myObjInner name : test myObjInner -> innerFun |
private접근자로 선언해야 외부에서 이용할 수 있는 이유는 다음과 같다. object클래스인 myObjInner클래스는 타입이 없기에 Any타입으로 인식된다. Any타입이어서 결국 프로퍼티 및 메서드는 없기에 외부에서 맴버 접근시 오류가 발생된다. private접근자로 선언하면 내부에서만 사용하겠다는 의미로 object타입 그대로 반환되어 맴버들이 그대로 노출되어 접근이 가능하다. object와 { } 사이에 클래스명을 명시해 선언할 수도 있다. 클래스명이 명시된 object클래스는 선언과 동시에 클래스명과 같은 이름의 객체까지 생성된다. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | class NormalClass { fun myFun() { println("NormalClass -> myFun"); } } object ObjectClass { fun myFun() { println("ObjectClass -> myFun"); } } val obj1: NormalClass = NormalClass(); val obj2: ObjectClass = ObjectClass(); // 오류 발생 obj1.myFun(); ObjectClass.myFun(); | cs |
실행 결과 NormalClass -> myFun ObjectClass -> myFun |
클래스명이 명시된 object 클래스인 ObjectClass는 선언과 동시에 해당 객체가 생성되었기 때문에 바로 해당 클래스 이름으로 해당 맴버에 접근이 가능하다. C#의 static처럼 사용이 가능하다. 하지만 | val obj2: ObjectClass = ObjectClass(); | cs |
|
처럼 object클래스를 직접 객체 생성시에는 오류가 발생한다.
클래스명이 명시된 object클래스는 특정 클래스 안에 작성할 수도 있다.
| class Outer { object NestedClass { val no: Int = 0; fun myFun() { println("NestedClass -> myFun"); } } } val obj:Outer = Outer(); obj.NestedClass.myFun(); // 오류 발생 Outer.NestedClass.myFun(); | cs |
실행결과 NestedClass -> myFun |
Outer클래스 안에 object NestedClass클래스가 선언되어 있고 NestedClass의 맴버에 접근할때는 바로
| Outer.NestedClass.myFun(); | cs |
|
식으로 접근이 가능하다. | val obj:Outer = Outer(); obj.NestedClass.myFun(); | cs |
|
위 식의 접근은 오류 발생한다. Outer클래스에서 NestedClass내부 맴버에 위 같은 식으로 접근할 수는 있는데 항상 부모 클래스인 Outer을 통해 접근할 수만 있다. 이때 companion예약어를 같이 사용하면 object클래스의 맴버를 object클래스명을 사용하지 않고 바로 접근할 수 있다. | class Outer { companion object NestedClass { val no: Int = 0; fun myFun() { println("NestedClass -> myFun"); } } } Outer.myFun(); | cs |
실행결과 NestedClass -> myFun |
위 처럼 companion object를 이용하면 static같은 효과를 낼 수 있다.
|