지난 part4에서는 Data Class, Nested Class와 Inner클래스에 대해서 정리해 보았습니다.
이전 글은 아래링크를 클릭해주세요
>> Kotlin을 배워보자 part4 (Data Class, Nested and Inner Class)
이번 part5에서는 익명 inner class에 사용되는 Object Expression,
Singleton패턴을 위한 Object Declaration
그리고 Java의 Static 함수를 대신하기 위해 사용하는 Companion Object 에 대해 정리해 보겠습니다.
1. Object Expression and Declaration
1-1. Object Expression
Object Expression은 특정타입으로부터 상속받는 Anonymous 클래스의 객체를 생성해 주는데요.
class 라는 키워드를 사용하지 않고 object라는 키워드 만으로 객체를 생성해줍니다.
이 Object Expression 을 사용하는 경우는 크게 2가지 경우가 있는데요.
- 보통은 일시적으로, 한번만 사용할 Anonymous 클래스의 객체 생성해 사용할 때
- 특정 클래스로부터 상속받는 어떤 클래스를 변경해 익명으로 변형된 객체를 전달해 줄 경우
문장만 봐서는 역시나 이해하기가 조금 어렵습니다.
예를 보면서 다시 정리해 보겠습니다.
A. 일시적으로 사용할 Anonymous(이름없는) 클래스의 객체를 생성해 사용하기
object 키워드로 일시적으로 사용해 볼 anonymous 객체를 생성해 보겠습니다.
아래는 공식문서에 나온 예인데요.
helloWorld라는 객체를 클래스이름없이 만들어서 생성하였습니다.
아래에서도 클래스 이름없이 객체로서 adHoc변수에 대입되어 사용되어졌습니다.
B. 특정 클래스를 상속받아 익명으로 변형된 객체를 생성해서 전달할 때
이 케이스를 이해하기에 좋은 예가 있는데요.
마우스클릭이벤트 같은 콜백 이벤트입니다.
굳이 상속받은 클래스를 만들지 않고 익명 클래스의 객체를 만들어서 전달해 주는 경우인데요.
아래에서는 MouseAdapter를 상속받는 익명의 클래스가 있습니다.
이 클래스는 mouseClicked와 mouseEntered를 override해서 필요에 맞게 재정의 하였는데요.
기존 클래스를 상속받아서, 변형을 해서 객체를 전달하려고 한 경우에 해당합니다.
이렇게 만든 객체를 addMouseListener에게 전달해 주기만 하면 되는 것 이지요.
안드로이드에서 실제 적용된 예를 보도록 하겠습니다.
View.OnClickListener 클래스를 상속받고 onClick을 override한 익명의 클래스의 객체를 받아서
setOnClickLIsterner에 넘겨주었습니다.
물론 위와 같이 변경해야 할 함수가 하나뿐인 경우 람다식으로 심플하게 아래와 같이 사용할 수 있습니다.
이 작업은 Android Studio가 클릭한번으로 도와주지만 말이지요.
그래도 이렇게 간결한 표현식도 위의 과정이 있었다는 것은 알고 있어야 하겠지요.
주의할 점은, 아래와 같이 상속받으려고 하는 클래스에 생성자가 있는 경우에는 인자를 넘겨주어야 합니다.
아래는 A클래스와 B인터페이스를 상속 및 구현하며
변수를 override하는 클래스의 익명의 객체를 만들어 ab에 담는 코드입니다.
object Expression을 이용함에 있어서 주의해야 할 것은
private이나 local로 사용되지 않고 public으로 사용된다면,
익명객체에 들어가 있는 변수나 함수에 접근할 수 없다는 점 입니다.
아래의 코드를 보면 private으로 표현된 object Expression에서는 name에 접근 가능하였지만,
public인 object Expression에는 에러가 난다는 것을 알 수 있습니다.
여기까지 object Expression에 대해서 알아보았는데요.
object declaration이라는 것도 있습니다.
1-2. Object Declarations
object declaration은 Kotlin에서 싱글턴 패턴을 쉽게 사용하도록 해 주는데요.
다음과 같은 조건을 만족시키고 사용하게 됩니다.
- object키워드 뒤에 선언할 객체 명 선언
- 생성자등을 이용해 객체를 생성하지 않음
- 객체명없이 object declaration을 한 이름을 통해 접근
- 상속은 가능(슈퍼타입을 가질 수 있음)
아래 kotlin코드를 decompile해보면 왜 싱글턴 패턴을 사용하게 해주는지 알 수 있는데요.
위 코드를 디컴파일 해주면 아래와 같이 싱글턴 패턴의 Java파일을 만들어 주는 것을 알 수 있습니다.
실제로 object declaration을 이용하는 코드를 보도록 하겠습니다.
아래와 같이 Singleton을 위한 객체를 선언해주구요.
선언한 객체명을 통해서 접근하는 것을 볼 수 있습니다.
위애서 언급하였던 것 처럼, 다른 클래스로부터의 상속이나, 여러 인터페이스의 구현도 가능한데요.
아래에서는 MouseAdapter 클래스를 상속하였습니다.
한가지 알아 두어야 할 점은,
object expression이 즉시 초기화 되어 객체가 생성되는 반면,
object declaration은 lazy(나중에)하게 객체에 처음으로 접근되어질 때, 초기화 되는데서 차이가 존재한다는 점 입니다.
전자는 객체가 바로 생성되는 것이고, 후자는 객체를 선언만 하고 나중에 생성되는 lateinit 인 것이지요.
object declaratin이 Cold한 특성을 가지고 있다고 하겠습니다.
다시 한번 정리하면,
object Declaration은 한번 객체가 만들어지고 나서,
처음으로 접근되어 질 때가 되서야 lazy하게, 메모리상에 초기화 되서 올라가구요.
대신 다시 부르더라도 새로운 객체로 생성되어지지 않고, 싱글턴과 같이 그 객체를 그대로 사용합니다.
따라서 객체가 가지고 있는 값도 유지되겠지요. (그러기 위해서 Singleton 패턴을 사용하는 것 이니까요.)
2. Companion Object
Kotlin에서는 Static 함수라는 것이 없어서,
Java에서 개발하던 개발자는 Kotlin을 만나면 당황하게 되는데요.
이 때 사용할 수 있는 것이 Companion Object 입니다.
Companion Object는 class안에 Object Declaration을 하면서 앞에 companion이라는 키워드를 붙여주면 되는데요.
즉, Class내부에서 하는 object declaration에 companion 이라는 키워드를 붙이는 것 입니다.
이렇게 함으로서, 해당 Class에서 Companion object의 멤버 변수나 함수에 대해 바로 접근이 가능합니다.
(Static class의 변수나 함수에 대해 그랬던 것처럼 말이지요.)
아래에서도 create멤버 함수에 클래스명을 통해 바로 접근이 가능하였습니다.
Companion Object는 아래와 같이이름을 생략해도 됩니다.
보통은 이름없이 많이 사용하지요. (이름 없어도 바로 접근이 가능하니 굳이 이름을 만들필요도 없겠지요)
대신 이 companion object에 접근할 때는 아래와 같이 Companion 키워드로 접근해야 합니다.
참고로, companion object는 클래스가 로드될 때 초기화 되어 집니다.
Java의 static initializer와 비슷하다고 할 수 있습니다.
한가지 주의할 점은, Companion Object의 변수나 함수가 static하다고 생각하면 않된 다는 점 입니다.
Koltin에는 Static이라는 것 자체가 존재하지 않기 때문인데요.
Companion Object는 상속이나 구현이 가능한 객체일 뿐입니다.
3. 정리
이번 part5에서는 Object Expression, Object Declaration 그리고 Companion Object 에 대해 정리해 보았습니다.
이렇게 해서 기본적으로 Kotlin에 대해 알아야 하는 부분들에 대한 글은 part5인 이 글을 통해 마무리가 되었구요.
Kotlin에 대한 다른 주제의 글들을 계속 블로그에서 다루도록 하겠습니다.
'Android 개발 > Kotlin' 카테고리의 다른 글
vararg 로 가변 인자를 전달하는 방법 #Kotlin (0) | 2020.05.11 |
---|---|
Kotlin으로 Android개발 하기 (0) | 2019.10.22 |
Kotlin Coroutine에 대한 정리 (0) | 2019.10.09 |
Kotlin에서 활용하는 Generic (0) | 2019.10.06 |
Scope Function 총정리 # Kotlin also let run with apply (0) | 2019.09.29 |
Kotlin을 배워보자 part4 (Data Class, Nested and Inner Class) (0) | 2019.09.27 |
Kotlin을 배워보자 part3 (Class, Constructor, 상속) (0) | 2019.09.26 |
Kotlin 을 배워보자 part2(if, when, map, for, while, array, list, singleOrNull, ranges, return with label) (0) | 2019.09.25 |
Kotlin을 배워보자 part1(Basic Types, Function, Null, 타입 변환, Lambda, 고차함수, Elvis, inline) (0) | 2019.09.24 |
Kotlin(코틀린)의 Sequence에 대해 알아보자 (0) | 2019.08.16 |
댓글