Kotlin 기본 문법 다루기

JJAE WON·2021년 9월 2일
0
post-thumbnail

이 게시글은 유투버 Code with Joyce 님의 강의를 보고 작성하였습니다.



1. 함수 사용 방법

  • return 값에 상관없이 모두 fun 함수명() 으로 통일한다.
    return 값이 있을 경우 fun 함수명(): Unit 으로 선언한다.
  • 파라메터를 전달할 때 변수명을 타입보다 먼저 선언해야 한다.
fun helloWorld(){
    println("Hello world!")
}

fun add(a: Int, b:Int) : Int{
    return a+b;
}

fun add(a: Int, b : Int) = a + b //expression 표현식

2. val VS var

fun hi(){
    val a : Int = 10
    var b = 9  // 자동으로 타입을 선언해준다. 타입 추론 가능

		//a = 9 => error!
    b = 100
}

val는 상수로 바뀌지 않는 값을 뜻한다. 변수에 한번 값을 초기화했을 경우 나중에 다른 값으로 할당할 수 없다. 자바에서 final과 비슷하게 사용

var는 변수를 다른값으로 바꿔서 사용할 수 있다.


3. String template

val name = "Jaewon"
println("my name is ${name} !!")
println("is this true? ${1==0}")
println("this is 2\$!!")

/*

my name is Jaewon !!
is this true? false
this is 2$!!

*/

4. 조건문

4-3. Expression과 Statement

코드 단위인 Expression과 Statement가 있는데 Kotlin의 함수와 조건문은 java에서와 다르게 Expression으로 표기가 가능하다.

  • Expression : 하나 이상의 값으로 표현 될 수 있는 코드
  • Statement : 실행 가능한 최소의 독립적인 코드조각

Expression은 Statement의 부분집합이다. 따라서 Ex는 St가 될 수 있지만 St는 모두가 Ex가 될 수 없다.

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

maxBy의 코드를 maxBy2로 표현할 수 있다.

여기서 maxBy와 maxBy2 모두 Expression이다. 왜냐하면 코틀린의 함수는 반환값이 없어도 모든 함수가 Unit을 반환하고 있기 때문에 모든 함수가 Expression으로 표기된다.

하지만 maxBy에서 조건문은 Statement로 표기되었고 maxBy2에서 조건문은 Expression으로 표기되었다.

자바에서는 void 함수가 리턴값이 없기 때문에 Statement로 표기된 함수이다. 그리고 자바에서 조건문은 모두 Statememt로 표기된다.

4-2. When

switch문과 비슷하다.

fun checkNum(score : Int){
    when(score){
        0 -> println("this is 0")
        1 -> println("1")
        2,3 -> println(" 2 or 3")
        else-> println(" 0~3이 아니다.")
    }
		// 조건문이 statement로 사용될땐 else문이 없어도 된다.

    var b = when(score){
				0 -> 0
        1 -> 1
        2 -> 2
        else -> 3
    }
   //조건문이 expression으로 사용될땐 else문이 꼭 있어야 한다.

    println("b : ${b}")

    when(score){
        in 1..3 -> println("1~3")
        in 4..5 -> println("4~5")
        else -> println("1~3이 아니다.")
    }
}

/* 
입력 0
출력
this is 0
b : 0
1~3이 아니다.
*/
  

5. Array, List

mutableList (수정가능) = arrayList , Array

inmutableList (수정불가능) = List

		// 초기화 방법    
		val array  = arrayOf(1,2,3)
    val list = listOf(1,2,3)

		// 여러 타입 초기화 가능
    val array2 = arrayOf(1,"d",3.4f)
    val list2 = listOf(1,"d",3.4f)

    array[0] = 3 // 변경가능
    //list[0] = 2 // 리스트의 원소 변경 불가능, 읽기전용
    var result = list.get(1)

		// 데이터 추가
    var arrayList = arrayListOf<Int>()
    arrayList.add(10)
    arrayList.add(20)

6. 반복문

6-1. For

val students = arrayListOf("jaewon","sungmin","bubble","danchoo")

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

for((index,name) in students.withIndex()){
    println("${index+1}번째 학생 : ${name}")
}

for (i in 10 downTo 1){
    sum += i
}

for (i in 1 until  100){
    sum += i
}

6-2. While

while (index < 10){
        println("index : ${index}")
        index++
}

7. Nullable / NonNull

자바에서는 NPE를 컴파일 시점에서 잡을 수 없고 런타임 시점에서만 체크할 수 있기 때문에 런타임 오류로 많이 발생한다.

코틀린에서는 컴파일 시점에서 null 체크를 해주므로 매우 편하다!!

7-1. ? 연산자

  • null 값이 들어갈 수 있는 변수를 선언할 때는 type 뒤에 ?를 붙여준다.
var name : String = "jaewon"
var nullName : String? = null
  • null 값인지 체크하기 위해서는 변수명 뒤에 ?를 붙여준다.
var nameInUperCase : String = name.toUpperCase()
var NullNameUPerCase : String? = nullName?.toUpperCase()
// nullName 변수가 null 값이면 'null'을 반환하고 null이 아니면
// 메서드를 실행시킨다.  nullName 뒤에 ?가 붙지 않으면 컴파일오류

7-2. ?: 엘비스연산자

  • 변수가 null 일 때 디폴트 값을 주거나 null 값을 변환할 수 있는 함수의 결과를 만들어 준다.
val lastname : String? = null

val fullname : String? = name+" "+(lastname?: "No lastName")
val name1 : String? = lastname?: return
val name2 : String? = lastname?: throw NullPointerException()

7-3. !!

  • 선언된 값이 절대절대 null이 아닐경우 !! 연산자로 선언을 해주면 뒤에서 계속 null값 체크를 하지 않아도 된다.
fun ignoreNull(str : String?){
    val mNotNull : String = str!!
    val upper = mNotNull.toUpperCase()
}

str이 null값이 아니라고 보증을 하였기 때문에 두번째 실행문에서 ?를 적지 않아도 에러가 발생하지 않는다.

7-4. ?.

  • null을 안전하게 처리하기 위해 사용한다. null이 아닐때 오른쪽에 있는 함수가 실행되고 아니면 null을 반환한다.
val email : String? = "ashwon12"
    email?.let {
        println("my email is ${email}")
    }

8. Class

  • 자바와 다르게 파일명과 클래스 이름이 일치하지 않아도 된다.

8-1. class 생성

class Person constructor(val name : String = "익명"){
    open fun eatingCake(){
        println("${name}이 말하길,,,케이크는 맛있다!")
    }
}

fun main(){
		val person1 = Person("jaewon")
		val person2 = Person()
		person1.eatingCake()
		person2.eatingCake()
}

/* 
출력
jaewon이 말하길,,, 케이크는 맛있다! 
익명이 말하길,,, 케이크는 맛있다! 
*/
  • 기본생성자는 클래스 선언문 옆 constructor()를 통해 생성해준다. 생략하고 괄호만 적어도 된다.
  • 매개변수로 전달받는 값은 바로 괄호 옆 생성자로 생성해주고 값이 없다면 초기화 값을 적어줄 수 있다.
  • 객체를 생성할 땐 자바와 다르게 new 를 생략해서 적어준다.

8-2. 부생성자과 init생성자

class Person constructor(val name : String = "익명" ){
    init {
        println("주 생성자의 일부!, 객체 생성!")
				println("person is ${name}")
    }

    constructor(name : String, age : Int) : this(name){
        println("my name is ${name}, age is ${age}")
    }
}

fun main(){
    val person = Person("jaewon")
    val person2 = Person()
    val sungmin = Person("sungmin",25)
}

/*
출력
주 생성자의 일부!, 객체 생성!
person is jaewon
주 생성자의 일부!, 객체 생성!
person is 익명
주 생성자의 일부!, 객체 생성!
person is sungmin
my name is sungmin, age is 25
*/
  • init 생성자는 주생성자가 호출될 때마다 호출되는 생성자이다. 객체를 생성하거나 자식클래스의 생성자가 호출할 때 자동으로 호출된다.
  • 부생성자는 주생성자에서부터 오기 때문에 주생성자에서 받은 값을 this()를 통해 전달시켜주어야 한다.

8-3. 상속과 오버라이딩

open class Person constructor(val name : String = "익명"){
    init {
        println("주 생성자의 일부!, 객체 생성!")
    }

    open fun eatingCake(){
        println("${name}이 말하길,,,케이크는 맛있다!")
    }
}

class onePerson() : Person(){
    override fun eatingCake(){
        //super.eatingCake()
        println("${name}은 cake를 싫어해!")
    }
}

fun main(){
    val person = Person("jaewon")
    person.eatingCake()

    val person2 = onePerson()
    person2.eatingCake()
}

/*
출력
주 생성자의 일부!, 객체 생성!
jaewon이 말하길,,,케이크는 맛있다!
주 생성자의 일부!, 객체 생성!
익명은 cake를 싫어해!
*/
  • 코틀린에서는 class와 메소드 모두 final로 선언되어 있기 때문에 open 명령어가 없으면 상속과 오버라이딩이 불가능하다.
  • 상속 선언 방법 class 자식클래스() : 부모클래스()



profile
안드왕 찐천재가 되고싶다.

0개의 댓글