728x90
5장 - 객체 생성
코틀린에서는 정적 메서드(static method) 를 사용할 수 없다
자바 static method 와의 비교
1. Companion Object
- 클래스와 연결된 싱글톤 객체
class MyClass {
companion object {
fun myStaticMethod() {
println("This is a static-like method")
}
}
}
// 사용 방법
MyClass.myStaticMethod()
2. Top-Level Functions
- 클래스 외부에 정의된 함수. 정적 메서드처럼 클래스 인스턴스 없이 호출할 수 있다.
fun myTopLevelFunction() {
println("This is a top-level function")
}
// 사용 방법
myTopLevelFunction()
3. Object Declarations
- 싱글톤 객체를 정의한다. 정적 메서드처럼 사용할 수 있다.
object MySingleton {
fun myMethod() {
println("This is a method in a singleton object")
}
}
// 사용 방법
MySingleton.myMethod()
더보기
네, 자바의 정적 메서드와 코틀린의 Companion Object는 매우 유사합니다. 둘 다 클래스의 인스턴스 없이 호출할 수 있고, 둘 다 인스턴스 변수에 접근할 수 없습니다. 하지만 몇 가지 차이점이 있습니다. 이를 간단하게 요약해보겠습니다.
자바의 정적 메서드와 코틀린의 Companion Object의 유사점과 차이점
유사점
- 클래스 인스턴스와 독립적:
- 자바: 정적 메서드는 클래스 인스턴스 없이 호출할 수 있습니다.
- 코틀린: Companion Object의 메서드도 클래스 인스턴스 없이 호출할 수 있습니다.
- 인스턴스 멤버 접근 불가:
- 자바: 정적 메서드는 클래스의 인스턴스 변수나 인스턴스 메서드에 접근할 수 없습니다.
- 코틀린: Companion Object의 메서드도 클래스의 인스턴스 변수나 인스턴스 메서드에 접근할 수 없습니다.
차이점
- 정의 방식과 위치:
- 자바: static 키워드를 사용하여 클래스 내부에 정적 메서드를 정의합니다.
- 코틀린: companion object 블록을 사용하여 클래스 내부에 싱글톤 객체를 정의하고 그 안에 메서드를 정의합니다.
- 싱글톤 패턴:
- 자바: 정적 메서드는 기본적으로 싱글톤 패턴과 관련이 없습니다.
- 코틀린: Companion Object는 기본적으로 싱글톤 패턴을 따릅니다.
- 상호 운용성:
- 코틀린: @JvmStatic 어노테이션을 사용하면 Companion Object의 메서드를 자바에서 정적 메서드처럼 호출할 수 있습니다.
- 팩토리 함수란:
- 클래스의 인스턴스를 생성하는 함수를 의미합니다. 생성자(constructor)와 달리, 더 구체적인 이름을 가질 수 있고, 다양한 인스턴스 생성 로직을 포함할 수 있습니다.
- 팩토리 함수의 장점:
- 더 나은 가독성: 팩토리 함수는 인스턴스를 생성하는 목적을 명확하게 설명하는 이름을 가질 수 있습니다. 예를 들어, createFromJson()과 같은 이름은 무엇을 하는 함수인지 명확히 나타냅니다.
- 다양한 반환 타입: 팩토리 함수는 동일한 타입의 여러 서브클래스를 반환할 수 있습니다. 생성자는 항상 특정 클래스의 인스턴스를 반환해야 하지만, 팩토리 함수는 다양한 서브클래스나 이미 생성된 인스턴스를 반환할 수 있습니다.
- 캐싱: 팩토리 함수는 이미 생성된 인스턴스를 반환하여 불필요한 객체 생성을 방지할 수 있습니다.
- 캡슐화: 객체 생성 로직을 클래스 내부에 캡슐화하여, 클라이언트 코드에서 복잡한 생성 과정을 숨길 수 있습니다.
class MyClass private constructor(val value: Int) {
companion object {
// 팩토리 함수
fun create(value: Int): MyClass {
return MyClass(value)
}
}
}
fun main() {
val instance = MyClass.create(42)
println(instance.value)
}
MyClass의 생성자가 private으로 설정되어 직접적으로 인스턴스를 생성할 수 없다.
대신 companion object 내에 create라는 팩토리 함수를 제공하여 인스턴스를 생성한다.
======================================
// 캐싱을 활용한다면..
class MyClass private constructor(val value: Int) {
companion object {
// 객체를 캐싱할 맵
private val cache = mutableMapOf<Int, MyClass>()
// 팩토리 함수
fun create(value: Int): MyClass {
// 캐시에서 객체를 조회, 없으면 생성 후 캐시에 저장
return cache.getOrPut(value) { MyClass(value) }
}
}
}
fun main() {
val instance1 = MyClass.create(42)
val instance2 = MyClass.create(42)
println(instance1 === instance2) // true, 동일한 객체를 가리킴
}
728x90
'공부 > 이펙티브코틀린' 카테고리의 다른 글
아이템35 - 복잡한 객체를 생성하기 위한 DSL을 정의하라 (0) | 2024.07.11 |
---|---|
아이템 34 - 기본 생성자에 이름 있는 옵션 아규먼트를 사용하라 (0) | 2024.07.11 |
아이템 32 - 추상화 규악을 지켜라 (0) | 2024.07.04 |
아이템 31 - 문서로 규악을 정의하라 (0) | 2024.07.02 |
아이템 30 - 요소의 가시성을 최소화하라 (0) | 2024.07.02 |
댓글