[Lecture] Kotlin 문법 종합반 KDT 실무형 Android 앱개발자 1회차 (5주차)_Part 1

Minjun Kim·2023년 7월 21일
0
post-thumbnail

유용한 기능


데이터 타입의 변환

일반 자료형

  • 숫자 자료형끼리는 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) {

  }

자료형 타입 확인

is 키워드

  if(name is String) {
      println("name은 String 타입입니다")
  } else {
      println("name은 String 타입이 아닙니다")
  }

여러 인스턴스를 리턴

  • 메소드는 기본적으로 하나의 데이터 를 리턴한다.

  • 2개 이상의 데이터를 포함하는 데이터클래스를 설계하고 인스턴스를 리턴하면 가능하지만,
    매번 불필요한 클래스를 생성 해야함으로 비효율적이다.

  • Kotlin은 PairTriple 키워드를 사용

  • 객체 형태 로 리턴함으로써, 1개의 값으로 쉽게 전달할 수가 있음

Pair

  • 2개의 인스턴스 리턴
// Pair : 2개의 인스턴스 리턴

  class Chicken {
      fun getEggs(): Pair<String, String> {
          var eggs = Pair("달걀", "맥반석")
          return eggs
      }
  }

Triple

  • 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()

Scope Functions

  • 객체의 컨텍스트 내에서 특정 동작(포로퍼티 초기화, 활용 등) 을 위한 목적만을 가진 함수

  • 자기 자신의 객체를 전달해서 효율적인 처리 가능

  • 즉, 객체의 이름을 일일히 참조할 필요 없이 객체를 접근하고 핸들링할 수 있다

Kotlin에서는 총 5가지의 스코프 함수를 제공한다.
[ let also run apply with ]

스코프 함수 정리표

키워드객체 참조리턴값
letit마지막 줄
alsoit참조 객체
runthis마지막 줄
withthis마지막 줄
applythis참조 객체

let : it, 마지막 줄을 반환

also : it, 참조 객체를 반환, apply와 함께 자주 사용함

run : this, 마지막 줄을 반환, 객체가 호출할 때/아닐 때로 나뉨

with : this, 마지막 줄을 반환 (반드시 null이 아닐때만 사용 = null이 아님을 보장)

apply : this, 참조 객체를 반환 (주로 객체의 상태를 변화시키고 바로 저장하고 싶을 때 사용)

let

  • it

  • 마지막 줄을 반환

  var strNum = "10"

  var result = strNum?.let {
      // 중괄호 안에서는 it으로 활용함
      Integer.parseInt(it)		// "10"을 10으로 변환한 값을 return
  }

  println(result!!+1)

also

  • 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} 입니다")
      }
  }

run

  • this

  • 마지막 줄을 반환

2가지 경우로 나뉜다.

  • 객체에서 호출하지 않는 경우
  • 객체에서 호출하는 경우로 나뉜다.

객체에서 호출하지 않는 경우

  var totalPrice = run {
      var computer = 10000
      var mouse = 5000

      computer+mouse		// 15,000을 return
  }
  println("총 가격은 ${totalPrice}입니다")

객체에서 호출하는 경우

  • with와 달리 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} 입니다")
      }
  }

with

  • this

  • 마지막 줄을 반환 (반드시 null이 아닐때만 사용 = null이 아님을 보장)

  var alphabets = "abcd"

  with(alphabets) {
      var result = this.subSequence(0,2)
      var result = subSequence(0,2)
      println(result)		// "ab"를 return
  }

apply

  • 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} 입니다")
	}
}

Scope function 정리

  • 수신객체는 thisit 으로 사용 가능

  • 크게 두 가지로 구분할 수 있음
    - 명시적으로 수신객체 자체를 람다로 전달하는 방법
    - 수신객체를 람다의 파라미터로 전달하는 방법

가장 중요한 포인트

  • 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
  }
profile
응애 나 아기 뉴비

0개의 댓글