Kotlin 문법

Jiyeahhh·2021년 11월 18일
0

강의
https://youtu.be/IDVnZPjRCYg
https://youtu.be/Q5noYbbc9uc


1. 함수

  • Unit = void , 안 써도 무방
fun helloWorld() : Unit {
    println(“Hello World!);
}
  • 형은 대문자로 적어야 하며, 변수명타입보다 먼저 쓴다.
fun add(a : Int, b : Int) : Int {
    return a+b
}

2. val vs var

💡 val = value

  • 변할 수 없는 값 : value
  • 변할 수 있는 값 : variable
fun hi() {
    val a : Int = 10  // 변할 수 없는 값 (value)
    var b : Int = 9  // 변할 수 있는 값 (variable)
    // a = 100 -> 에러!
    b = 100  // 에러 x
    
    // 굳이 Int라고 안 적어줘도 됨
    val c  = 100
    var d = 100

    // 형은 생략, 자동 추론!, but 바로 값을 할당할 때는 선언을 해줘야 함
    var name = ‘jiye’
    var e : String
}

3. String Templete

val name = “Jiye”
val lastName = “An”

// 대괄호를 써주는 습관!
println(“my name is ${name + lastName} I’m 22)

println(is the true? ${1==0})

println(this is 2\$a”)

4. 조건식

fun maxBy(a : Int, b : Int) : Int {
    if(a > b) {
        return a
    } else {
        return b
    }
}

fun maxBy2(a : Int, b : Int) = if(a>b) a else b

fun checkNum(score : Int) {
    when(score) {   // switch와 같은 개념
        0 -> println(this is 0)
        1 -> println(this is 1)
        2, 3 -> println(this is 2 or 3)
        else -> println(“I don’t know”)   // 안 써도 무방
    }

    var b = when(score) {
        1 -> 1
        2 -> 2
        else -> 3   // 이럴 때는 else를 꼭 써줘야 함!
    }

    println(“b : ${b})

    when(score) {
        in 90..100 -> println(“You are genius”)
        in 10..80 -> println(“not bad”)
        else -> println(“okay”)
    }
}

5. Array and List

  • List : 1. List (수정 불가능) 2. MutableList (수정 가능)
fun array() {
    val array = arrayOf(1, 2, 3)
    val list = listOf(1, 2, 3)
 
    // Any 타입으로 자동 추론
    val array2 = arrayOf(1, “d”, 3.4f)
    val list2 = listOf(1, “d”, 11L)

    array[0] = 3
    // list[0] = 2 -> 에러!
    var result = list.get(0)    // get은 있지만 set은 없음

    var arrayList = arrayListOf<Int>()
    arrayList.add(10)
    arrayList.add(20)
}

6. 반복문 (For / While)

fun forAndWhile() {
    val students = arrayListOf(“jiye”, “james”, “jenny”, “jennifer”)

    for(name in students) {
        println(“${name})
    }

    var sum : Int = 0
    for (i in 1..10 step 2) {   // 1 3 5 7 9
        sum += i
    }
    println(sum)

    // for (i in 10 downTo 1) -> 10부터 10 9 8 …
    // for (i in 1 until 100) -> 1부터 99까지 (1.. 100과 다름)

    var index= 0
    while(index < 0) {
        println(“current index : ${index})
        index++
    }
}

7. Nullable / NonNull

fun nullcheck() {
    // NPE : NULL pointer Exception -> 돌려봐야 알 수 있음
    var name : String = “jiye”

    var nullName : String? = null   // ?를 붙이면 nullable 됨
 
    var nameInUpperCase = name.toUpperCase()

    // ?를 붙이면 nullName이 null이면 null을 반환하고, 아니면 대문자로 변환
    var nullNameInUpperCase = nullName?.toUpperCase()

    // ?:
    val lastName : String? = null

    // null일 때 default 값 주기
    val fullName = name+” “ + (lastName?: “No lastName”)   
    println(fullName)
}

// !!: nullable 선언했지만 null 값이 아니라는 걸 보장해줄게!
fun ignoreNulls(str : String?) {
    // 절대 null일리 없으니까 null이 아니라고 생각해!
    val mNotNull : String = str!!
    var upper = mNotNull.toUpperCase()

    var email : String? =jiyeXXXX@nana.vom”
    // let : lamda 식 내부로 옮겨줌
    email?.let {    // email이 null이 아니면 ~~~해라
        println(“my email is ${email})
    }
}

8. Class

  • 클래스 이름과 파일 이름이 동일하지 않아도 됨
  • 기본은 final, open을 해줘야 상속 가능
open class Human (val name : String = “Anonymous”) {   // constructor 생략 가능
    // val name = name

    constructor(name : String, age : Int) : this(name) {   // 부생성자
        println(“my name is ${name}, ${age}years old”)
    }

    init {   // 주생성자 ; 처음 class 인스턴스를 생성할 때 동작, 무조건 먼저 실행
        println(“New human has been born!!)
    }

    fun eatingCake() {
        println(“This is so YUMMMYYY~~~”0
    }
 
    // default final이기 때문에 open -> 오버라이딩 가능
    open fun singASong() {
        println(“lalala”)
    }
}

class Korean : Human() {
    override fun singASong() {
        super.singASong()    // 부모의 singASong()도 실행
        println(“라라랄”)
        println(“my name is ${name})
    }
}

fun main() {
    /*val human = Human(“jiye”)
 
    val stranger = Human()

    human.eatingCake()

    val mom = Human(“eunha”, 52)

    println(“this human’s name is ${stranger.name}”)*/

    val korean = Korean()
    korean.singASong()
}

9. Lamda

  • 람다식은 우리가 마치 value처럼 다룰 수 있는 익명함수!
    익명함수 : 함수 코드가 변수명에 저장된 형태
  • 메소드의 파라미터로 넘겨줄 수 있음
  • return 값으로 사용할 수 있음

9-1. 람다의 기본 정의

val lamdaName : Type = {argumentList -> codeBody}
  • 타입 추론이 가능
val square : (Int) -> (Int) = {number -> number*number}
// val square = {number : Int -> number * number}

val nameAge = {name : String, age : Int ->
    "my name is ${name} I'm ${age}"
}

fun main() {
    println(square(12))
    println(nameAge("jiye", 22))
}

9-2. 람다와 확장함수

  • this : 확장 함수가 불러 줄 object
  • it : 파라미터가 하나인 경우에는 it으로 생략 가능
// String 클래스에 추가
val pizzaIsGreat : String.() -> String = {
    this + "Pizza is the best!"
}

fun extendString(name : String, age : Int) : String {
    // this : 확장 함수가 불러 줄 object
    // it : 하나 들어가는 파라미터인 경우에는 it 으로 생략 가능
    val introduceMyself : String.(Int) -> String = {"I am ${this} and ${it} years old"}
    return name.introduceMyself(age)
}

fun main() {
    val a = "joice said "
    val b = "mac said "
    println(a.pizzaIsGreat())
    println(b.pizzaIsGreat())

    println(extendString("ariana", 27))
}

9-3. 람다의 Return

  • input parameter는 여러개일 수 있으므로 항상 소괄호를 적어줘야 함
// input parameter 는 여러개일 수 있으므로 항상 소괄호를 적어줘야 함!
val calculateGrade : (Int) -> String = {
    when(it) {
        in 0..40 -> "fail"
        in 41..70 -> "pass"
        in 71..100 -> "perfect"
        else -> "Error"     // else 안 쓰면 에러
    }
}

9-4. 람다를 표현하는 2가지 방법

// invokeLamda()는 Boolean 을 리턴함
// parameter 로 넣는 람다식을 사용 
// => 그 람다에 5.2343을 넣어서 리턴이 되는 Boolean 값을 invokeLamda()의 return 값으로 삼겠다는 뜻
fun invokeLamda(lamda : (Double) -> Boolean) : Boolean {
    return lamda(5.2343)
}

fun main() {
    // number가 4.3213과 다르면 false
    val lamda = { number: Double ->
        number == 4.3213
    }
    println(invokeLamda(lamda))
    println(invokeLamda({it > 3.22}))

    // function의 마지막 파라미터가 람다인 경우 다음과 같이 표현 가능
    println(invokeLamda { it > 3.22 })
}

10. Data Class

  • pojo 클래스 : 어떤 모델이 되는 클래스, 딱히 그 안에서 메소드 작동 x, 비어있으며 어떤 틀 역할을 하는 클래스
  • pojo 클래스를 만들기 위해서 java는 직접 일일이 써줘야 했음
  • 그런 쓸데없는 코드를 줄이기 위해 kotlin에서 쓰는 게 data class
  • data class를 한 파일에 모아서 정리하면 관리하기 용이
data class Ticket(val companyName : String, val name : String, var date : String, var seatNumber : Int)
// toString(), hashCode(), equals(), copy() => 컴파일하면 자동으로 만들어 줌

class TicketNormal(val companyName : String, val name : String, var date : String, var seatNumber : Int)

fun main() {
    val ticketA = Ticket("koreanAir", "joyceHong", "2020-02-16", 14)
    val ticketB = TicketNormal("koreanAir", "joyceHong", "2020-02-16", 14)
    // Ticket(companyName=koreanAir, name=joyceHong, date=2020-02-16, seatNumber=14) 출력
    println(ticketA)
    // org.techtown.kotlinpractice.TicketNormal@2acf57e3 => 메모리 주소 값 출력
    println(ticketB)
}

11. Companion Object

  • 자바의 static 대신에 사용되며, 정적인 메소드나 정적인 변수를 선언할 때 사용
class Book private constructor(val id : Int, val name : String) {
    companion object BookFactory : IdProvider {
        override fun getId(): Int {
            return 444
        }

        val myBook = "new book"
        fun create() = Book(getId(), myBook)
    }
}

interface IdProvider {
    fun getId() : Int
}

fun main() {
//    val book = Book.Companion.create()
    // Companion 생략 가능
    val book = Book.create()

    val bookId = Book.BookFactory.getId()
    println("${book.id} ${book.name}")
}

12. Object

  • Singleton Pattern
  • 실행될 때 딱 한 번 객체를 생성하고, 다신 생성 x
  • 불필요한 메모리 낭비 없앰
object CarFactory {
    val cars = mutableListOf<Car>()
    fun makeCar(horsePower: Int) : Car {
        val car = Car(horsePower)
        cars.add(car)
        return car
    }
}

data class Car(val horsePower : Int)

fun main() {
    // CarFactory를 사용하기 위해 객체를 생성하지 않음 - 실행될 때 만들어진 객체로 사용
    val car = CarFactory.makeCar(10)
    val car2 = CarFactory.makeCar(200)

    println(car)
    println(car2)
    println(CarFactory.cars.size.toString())

}
profile
람차람차

0개의 댓글

관련 채용 정보