-
[Kotlin] 코틀린 class (open, data , sealed, internal class)코틀린 공부/코틀린 기초 2024. 5. 17. 15:04
자바에는 없는 코틀린 class에서 다른 키워드들을 학습해보려고 한다. (open, data, internal class)
1. open class
기존에 자바에서는 일반 class를 상속하는 것이 가능했다.
class Parent{} class Child extends Parent{}
코틀린에서는 class를 상속하기 위해서는 open이라는 키워드를 같이 사용해야 한다. 왜냐하면 코틀린에서는 기본적으로 클래스와 메스드가 다 final 이기 때문이다.
open class Parent {} class Child:Parent() {}
메서드를 상속하고 싶다면 open을 붙여줘야 한다.
open class Animal(var name:String, var age: Int) { open fun introduce(){ println("Animal : $name $age ") } } class Dog(name:String, age:Int) : Animal(name, age){ override fun introduce(){ println("Dog : $name $age ") } }
결론적으로, class와 open class의 차이는 상속불가능 vs 상속 가능의 차이이다.
2. data class
일반 class에서 다양한 메소드를 자동적으로 생성해줘서 편리하게 사용하게 만들어진 것이 data class다.
같이 생성되는 것들
- hashCode()
- copy()
- equals()
- toString()
- componentsN()
메소드 설명 :
더보기- hashCode():
- hashCode() 메서드는 객체의 해시 코드를 반환합니다. 해시 코드는 주로 해시 테이블과 같은 자료 구조에서 객체를 빠르게 찾기 위해 사용됩니다.
- data class의 hashCode()는 모든 속성의 해시 코드를 기반으로 생성됩니다. 즉, 두 객체의 속성들이 모두 같다면, 이들의 해시 코드도 동일하게 생성됩니다.
- copy():
- copy() 메서드는 객체를 복사하는 메서드로, 선택적으로 일부 속성의 값을 변경할 수 있습니다.
- 예를 들어, val obj2 = obj1.copy(prop1 = newValue)와 같이 사용하면, obj1을 복사하되 prop1의 값을 newValue로 변경한 새로운 객체를 생성합니다.
- (코틀린에서는 일반적으로 모든 변수를 val로 선언해 불변으로 놓고 변해야 하는 변수가 있다면 copy를 사용해서 해당 변수만 바꿔서 복사해서 사용한다고 한다. )
- equals():
- equals() 메서드는 두 객체의 내용이 같은지 비교합니다.
- data class의 equals()는 모든 속성들이 동일한지 비교하여 동일하면 true, 그렇지 않으면 false를 반환합니다. 이를 통해 객체의 속성 값들을 기준으로 동등성을 판단합니다.
- toString():
- toString() 메서드는 객체의 문자열 표현을 반환합니다.
- data class의 toString()은 클래스 이름과 함께 각 속성의 이름과 값을 포함한 문자열을 반환합니다. 예를 들어, Person(name=John, age=30)과 같은 형태로 출력됩니다.
- componentN():
- componentN() 메서드는 각 속성을 반환하는 메서드로, 여기서 N은 속성의 순서를 나타냅니다.
- 예를 들어, component1()은 첫 번째 속성을, component2()는 두 번째 속성을 반환합니다.
- 이러한 메서드는 주로 Destructuring Declarations에서 사용됩니다. 예를 들어, val (name, age) = person과 같이 사용할 수 있습니다. 이는 component1()과 component2() 메서드를 호출하여 각각의 값을 할당합니다.
그리고 Data Class는 아래와 같은 규칙을 갖고 있어 알아둘 필요성이 있다.
- 기본 생성자 안에 1개 이상의 파라미터가 있어야 한다.
- 기본 생성자의 파라미터가 val 또는 var로 선언되어야 한다.
- 다른 클래스를 상속받을 수 없다. 단, sealed 클래스는 상속받을 수 있다.
- abstract, open, sealed, inner와 같은 keyword와 함께 사용할 수 없다.
fun main(){ val p1 = Person(30,"JJJ") val p2 = Person(30,"JJJ") // 내용이 같은지 검사 println(p1==p2) // 같은 인스턴스인지 검사 (즉, 메모리 주소가 같은지 검사한다는 것 같음) println(p1===p2) println(p1.toString()) val p3 = Person2(30, "JJJ") println(p3.toString()) } data class Person(val age: Int, val name: String) class Person2(val age: Int, val name: String) // 결과 true false Person(age=30, name=JJJ) com.example.kotlinpractice.class_example.data_class.Person2@3d24753a
3. Sealed class
코틀린에서 sealed class란 다른 클래스가 상속받지 못하도록 제한하는 클래스이다. sealed class의 하위 클래스에서만 상속받을 수 있다. 클래스 계층 구조에서 제한된 개수의 클래스를 나타낼때 사용하게 된다.
sealed class Vehicle { abstract val info:Int data class Car(val name: String) : Vehicle(){ override val info: Int get() = 1 } data class Truck(val name: String) : Vehicle(){ override val info: Int get() = 2 } }
sealed class 특징 :
- 상속을 제한한다.
- sealed class는 다른 클래스에서 상속을 받지 못하도록 제한한다. 그래서 sealed class의 내부에 정의해서 사용.
- 유한한 개수의 하위 클래스를 갖는다.
- 상속이 제한되기 때문에 유한한 개수의 하위 클래스를 가진다.
- 하위 클래스의 종류를 제한한다.
- 하위 클래스의 종류를 제한하여 클래스 계층 구조를 제한 할 수 있다.
sealed class 장점 :
- 1. 코드 안정성 향상
- 컴파일 타임때 모든 하위 클래스를 확인하고 사용할 수 있기 때문에 안정성 향상 가능
- 2. 가독성 향상
- 클래스 계층 구조가 명확해 지기 때문에 코드의 가독성이 향상되고 유지보수성이 향상
- 3. 패턴 매칭
- 패턴 매칭은 일반적으로 타입이 서로 다른 값들을 패턴으로 지정하고, 해당 값이 각각 어떤 타입인지 판별하는 기능이다. 이런 경우 가독성을 높일수 있다.
when (vehicle) { is Vehicle.Car -> println("car :${vehicle.name}.") is Vehicle.Truck -> println("truck : ${vehicle.name}.") }
만약 sealed class를 안썼다면 else를 추가해야 한다.
이것보다 더 간단하게 만들어보자면
sealed class Vehicle { abstract fun print() abstract val info:Int data class Car(val name: String) : Vehicle(){ override val info: Int get() = 1 override fun print() { println("This is a Car named ${name}.") } } data class Truck(val name: String) : Vehicle(){ override val info: Int get() = 2 override fun print() { println("This is a dog named ${name}.") } } }
fun printAnimalInfo(vehicle: Vehicle) { when (vehicle) { is Vehicle.Car -> println("car :${vehicle.name}.") is Vehicle.Truck -> println("truck : ${vehicle.name}.") } } fun printAnimalInfo2(vehicle: Vehicle) { vehicle.print() }
이런식으로도 사용 가능하다.
4. internal class
internal class는 자바에는 없기 때문에 이게 뭔지 혼란스러웠다. 그래서 우선 접근 제한자가 자바와 코틀린에더 어떻게 다른지 알아보자면
자바 :
- public : 접근을 제한이 없음
- protected : 동일한 패키지 내에 존재하거나 파생클래스에서만 접근 가능
- default : 아무런 접근 제한자를 명시하지 않으면 default 값이 되며, 동일한 패키지 내에서만 접근이 가능
- private : 자기 자신의 클래스 내에서만 접근이 가능
코틀린 :
- Private : 해당 파일이나 클래스에서만 사용을 가능하게 합니다.
- Public : 어디에서나 접근을 할 수가 있고, 만약 함수나 클래스 앞 아무것도 붙이지 않으면 디폴트로 지정이 되어서 따로 붙일 필요가 없습니다.
- Protected : 상속받는 인터페이스, 클래스 또는 자식 클래스에서 만 접근이 가능합니다.
- Internal : 코틀린에서 새롭게 추가된 접근 제한자이고, 같은 프로젝트 모듈 안 에서는 다 접근이 가능 합니다.
'코틀린 공부 > 코틀린 기초' 카테고리의 다른 글
[Kotlin] object (0) 2024.05.23 [Kotlin] 스코프 함수 (Scope Function) (0) 2024.05.23 [Kotlin] 고차함수와 람다함수 (0) 2024.05.22 [Kotlin] 추상 클래스와 인터페이스 (0) 2024.05.21 [Kotlin] 코틀린 생성자(Constructor) (0) 2024.05.17