숫자
자료형끼리는 to자료형()
메소드실수 -> 정수 : toInt()
정수 -> 실수 : toDouble()
문자열
을 숫자로 변경 시에는 별도의 메소드가 필요문자열 -> 정수 : Integer.parseInt(변수)
문자열 -> 실수 : toDouble()
상속관계
에서 가능
업 캐스팅
: 자식클래스를 부모클래스의 자료형으로 객체 생성
다운 캐스팅
: 부모클래스를 자식클래스의 자료형으로 객체 생성
// 업 캐스팅 예시
fun main() {
println("몇 마리를 생성하시겠습니까?")
var count = readLine()!!.toInt()
var birds = mutableListOf<Bird>()
for(idx in 0..count-1) {
println("조류의 이름을 입력해주세요")
var name = readLine()!!
// as Bird는 생략가능
birds.add(Sparrow(name) as Bird) //부모 클래스 자료형으로 객체 생성
}
println("============조류 생성완료============")
for(bird in birds) {
bird.fly()
}
}
open class Bird(name: String) {
var name: String
init {
this.name = name
}
fun fly() {
println("${name}이름의 조류가 날아요~")
}
}
class Sparrow(name: String): Bird(name) { // Bird 클래스를 상속
}
// 다운 캐스팅 예시
fun main() {
println("몇 마리를 생성하시겠습니까?")
var count = readLine()!!.toInt()
var birds = mutableListOf<Bird>()
for(idx in 0..count-1) {
println("조류의 이름을 입력해주세요")
var name = readLine()!!
birds.add(Sparrow(name) as Bird)
}
println("============조류 생성완료============")
for(bird in birds) {
bird.fly()
}
// 다운캐스팅 오류
// Sparrow는 Bird가 가져야할 정보를 모두 가지고 있지 않기 때문임
// var s1:Sparrow = birds.get(0)
}
open class Bird(name: String) {
var name: String
init {
this.name = name
}
fun fly() {
println("${name}이름의 조류가 날아요~")
}
}
class Sparrow(name: String): Bird(name) {
}
if(name is String) {
println("name은 String 타입입니다")
} else {
println("name은 String 타입이 아닙니다")
}
메소드는 기본적으로 하나의 데이터
를 리턴한다.
2개 이상의 데이터를 포함하는 데이터클래스를 설계하고 인스턴스를 리턴하면 가능하지만,
매번 불필요한 클래스를 생성 해야함으로 비효율적이다.
Kotlin은 Pair
와 Triple
키워드를 사용
객체 형태
로 리턴함으로써, 1개의 값으로 쉽게 전달할 수가 있음
2개의 인스턴스 리턴
// Pair : 2개의 인스턴스 리턴
class Chicken {
fun getEggs(): Pair<String, String> {
var eggs = Pair("달걀", "맥반석")
return eggs
}
}
3개의 인스턴스 리턴
// Triple : 3개의 인스턴스 리턴
fun getThreeEggs(): Triple<String, String, Int> {
var eggs = Triple("달걀", "맥반석", 20230101)
return eggs
}
}
var chicken = Chicken()
var eggs = chicken.getEggs()
var listEggs = eggs.toList()
객체의 컨텍스트 내에서 특정 동작(포로퍼티 초기화, 활용 등)
을 위한 목적만을 가진 함수
자기 자신의 객체를 전달해서 효율적인 처리 가능
즉, 객체의 이름을 일일히 참조할 필요 없이 객체를 접근하고 핸들링할 수 있다
Kotlin에서는 총 5가지의 스코프 함수를 제공한다.
[let
also
run
apply
with
]
키워드 | 객체 참조 | 리턴값 |
---|---|---|
let | it | 마지막 줄 |
also | it | 참조 객체 |
run | this | 마지막 줄 |
with | this | 마지막 줄 |
apply | this | 참조 객체 |
let
: it, 마지막 줄을 반환
also
: it, 참조 객체를 반환, apply와 함께 자주 사용함
run
: this, 마지막 줄을 반환, 객체가 호출할 때/아닐 때로 나뉨
with
: this, 마지막 줄을 반환 (반드시 null이 아닐때만 사용 = null이 아님을 보장)
apply
: this, 참조 객체를 반환 (주로 객체의 상태를 변화시키고 바로 저장하고 싶을 때 사용)
it
마지막 줄을 반환
var strNum = "10"
var result = strNum?.let {
// 중괄호 안에서는 it으로 활용함
Integer.parseInt(it) // "10"을 10으로 변환한 값을 return
}
println(result!!+1)
it
참조 객체를 반환
apply와 함께 자주 사용함
fun main() {
var student = Student("참새", 10)
var result = student?.also { // "참새", "50"의 객체를 return
it.age = 50
}
result?.displayInfo()
student.displayInfo()
}
class Student(name: String, age: Int) {
var name: String
var age: Int
init {
this.name = name
this.age = age
}
fun displayInfo() {
println("이름은 ${name} 입니다")
println("나이는 ${age} 입니다")
}
}
this
마지막 줄을 반환
2가지 경우로 나뉜다.
- 객체에서 호출하지 않는 경우
- 객체에서 호출하는 경우로 나뉜다.
var totalPrice = run {
var computer = 10000
var mouse = 5000
computer+mouse // 15,000을 return
}
println("총 가격은 ${totalPrice}입니다")
null체크
를 수행할 수 있음 fun main() {
var student = Student("참새", 10)
student?.run {
displayInfo() // student.displayInfo() 와 동일
}
}
class Student(name: String, age: Int) {
var name: String
var age: Int
init {
this.name = name
this.age = age
}
fun displayInfo() {
println("이름은 ${name} 입니다")
println("나이는 ${age} 입니다")
}
}
this
마지막 줄을 반환 (반드시 null이 아닐때만 사용 = null이 아님을 보장)
var alphabets = "abcd"
with(alphabets) {
var result = this.subSequence(0,2)
var result = subSequence(0,2)
println(result) // "ab"를 return
}
this
참조 객체를 반환 (주로 객체의 상태를 변화시키고 바로 저장하고 싶을 때 사용)
fun main() {
var student = Student("참새", 10)
var result = student?.apply { // "참새", "50"의 객체를 return
student.age = 50
}
result?.displayInfo()
student.displayInfo()
}
class Student(name: String, age: Int) {
var name: String
var age: Int
init {
this.name = name
this.age = age
}
fun displayInfo() {
println("이름은 ${name} 입니다")
println("나이는 ${age} 입니다")
}
}
수신객체는 this
와 it
으로 사용 가능
크게 두 가지로 구분할 수 있음
- 명시적으로 수신객체 자체를 람다로 전달하는 방법
- 수신객체를 람다의 파라미터로 전달하는 방법
가장 중요한 포인트
it
은 Scope Function을다중으로
사용할 때 문제가 발생할 수 있다.- Child Function에서 Shadow가 되어 제대로 참조하지 못할 수 있기 때문에
it
의 명칭을 변경해서 사용한다.
data class Person(
var name: String = "",
var age: Int? = null,
var child: Person? = null
)
// 잘못된 예시
Person().also {
it.name = "한석봉"
it.age = 40
val child = Person().also {
it.name = "홍길동" // 누구의 it인지 모른다!
it.age = 10 // 누구의 it인지 모른다!
}
it.child = child
}
// 수정한 예시
Person().also {
it.name = "한석봉"
it.age = 40
val child = Person().also { c -> // it의 명칭 변경
c.name = "홍길동"
c.age = 10
}
it.child = child
}