Kotlin 기본 문법

안드로이드 스튜디오에서 Kotlin 문법을 알아보도록 한다.

 

Kotlin으로 test파일을 만들어주자.

 

package com.example.kotlinwork

fun main() {
    print("kotlin test..")
}

실행법은 오른쪽 클릭 후 Run을 누르면 된다.

 

main 함수는

fun main() { } 이라고 표현한다.

print문은 파이썬과 같다. 단 print문은 줄바꿈이 없다.

println으로 해야 줄바꿈이 같이 된다.

 

파이썬처럼 println("""gg""".trimIndent())이게 가능하다.

단 문자열 뒤에 trimIndent()가 붙는다.

 

package com.example.kotlinwork.basic

fun main() {
    //변수 선언하는 방법
    //var 변수명 : 데이터타입
    //var 변수명 = 데이터타입
    //var 변수명 : 데이터타입 = 값
    //var로 선언한 변수는 읽기쓰기가 가능한 변수
    //val 변수명 : 데이터타입
    //val 변수명 = 데이터타입
    //val 변수명 : 데이터타입 = 값
    //val은 읽기만 가능한 변수 (상수같은 개념)
    var a : Int = 200
    var b : String = "my Kotlin"
    var c : Double = 10.5
    println(a)
    println(b)
    println(c)
    //코틀린은 데이터 타입을 생략할 수 있고, 선언한 수 있다
    var num = 100
    var data = "my kotlin"
    var point = 10.5
    val mydata = 300
    println(num)
    println(data)
    println(point)
    println(mydata)
    //mydata = 500 에러발생

    //변수의 활용
    var num3:Int = 1000
    var num4 = 2000
    val result:Int = num3+num4
    println("${num3}+${num4}=${result}")
    println("${num3}+${num4}=${num3+num4}")

    var data3 = "123"
    println("$data3") //문자열은 이렇게 출력
    println("${data3.toInt()}") // Int형으로 변형
    println("${data3.toDouble()}") // Double형으로 변형

    //변수에 null을 저장하기
    var num5 = 100
    var num6 = null
    println("값:${num5}")
    println("값:${num6}")

    var num7:Int = 100
    //var num8:Int = null 오류
    //null을 허용하지 않는 변수를 정의
    var num8:Int ? = null
    //? 붙이면 null 허용
    println("값:$num7")
    println("값:$num8")

    var num9:Int = num8!! //null허용하지 않는 타입을 맞춰주는 작업(컴파일오류를 처리하도록)
    //!!는 null은 허용했지만 이 시점에서 null이 아님을 보장하겠다는 의미
}
package com.example.kotlinwork.basic

fun main() {
    //매개변수가 없고 리턴값이 없는 함수의 호출
    test()
    //매개변수가 있고 리턴값이 없는 함수 호출
    test(100,200)
    test(100.2, 200)
    val result = mytest(100,200)
    println("result:$result")
    println("값:${mytest(200,300)}")
}
//매개변수가 없고 리턴값이 없는 함수
//Unit은 반환될 값이 없다는 의미로 해석 : void와 동일
fun test():Unit {
    println("test함수")
}
fun mytest(num1:Int, num2:Int):Int {
    //매개변수 옆에 :Int가 리턴타입
    val result = num1+num2
    return result
}

//매개변수가 있고 리턴값이 없는 함수
//함수명이 같아도 매개변수의 갯수나 매개변수의 타입이 다르면 같은 이름으로 여러 개 함수를 정의할 수 있다 - 오버로딩
fun test(num1:Int,num2:Int) {
    println("num1=$num1")
    println("num2=$num2")
    println("==============")
}
fun test(num1:Double,num2:Int=10000) {
    println("num1=$num1")
    println("num2=$num2")
    println("==============")
}

 

package com.example.kotlinwork.basic

import java.util.*

fun main() {
    val sc:Scanner = Scanner(System.`in`)
    print("문장을 입력하세요:")
    val line = sc.nextLine()
    print("성명:")
    val name = sc.nextLine()
    print("나이:")
    val age = sc.nextInt()

    println(line)
    println("name:$name, age:$age")
}

package com.example.kotlinwork.statement

fun main() {
    //when 구문 -> 다중분기(if ~ else if, switch문이라고 생각하면 됨)
    //사이값을 비교하는 경우는 if~else if
    //정확하게 일치하는 값을 비교하고 비교할 값들이 적은 경우
    /*when(변수 or 연산식 or 메소드호출문) {
        결과가 값으로 리턴
        값 1 -> 결과가 값1이면 실행할 명령문 작성
        값 2 -> 결과가 값2이면 실행할 명령문 작성
        값 3 -> {
            실행할 문장이 여러개인 경우
        }
        else -> 해당사항 없는것
    }*/
    val num1:Int = 2

    when (num1) {
        1 -> println("num1은 1")
        2 -> {
            println("num1은 2")
            println("여러줄 명령문")
        }
        3 -> println("num1은 3")
        4,5 -> println("4또는 5 입니다.")
        else -> println("해당사항 없음")
    }

    val num2 = 7
    when (num2) {
        in 1..3 , in 11..15 -> println("1부터 3")
        in 4..7 -> println("4부터 7")
        in 8..10 -> println("8부터 10")
    }

    //when을 실행할 결과를 함수의 리턴값으로 사용 - else문을 반드시 사용해야 함
    fun setValue(num:Int) = when(num) {
        1 -> "문자열1"
        2 -> "문자열2"
        else -> "그 외의 값"
    }

    val str1 = setValue(2)
    println("result1=>$str1")
    println("result2=>${setValue(2)}")
    println("result2=>${setValue(3)}")
}

package com.example.kotlinwork.etc

fun main() {
    //코틀린에서 Null관리
//    var num1:Int ?= null
//    var num2:Int = num1!!
    //null없는 경우 상관없는데 null이 있는 경우 에러
    fun testnull1(str:String?) {
        val value1:String = str!!
        println("value:$str")
        //문법적 오류는 해결, !!는 null에 대한 안정성을 보장받을 수 없다.
    }
    fun testnull2(str:String?) {
        //str매개변수가 null이면 "기본값"이 str에 할당되고
        //null아니면 전달된 값이 적용
        val value1:String = str?:"기본값"
        println("value:$value1")
        //변수에 null이 없으면 전달된 값을 할당하고 null이 있는 경우 기본값을 할당할 수 있도록 구현
    }
    testnull2("문자열")
    testnull2(null)

    fun testMethod1(str:String?) {
        println("문자열 길이 : ${str?.length}")
    }
    testMethod1("안녕하세요")
    testMethod1(null)
    
    fun testMethod3(str:String?) {
        if(str is String)
            println(str.length)
        if(str!=null)
            println(str.length)
    }
}

package com.example.kotlinwork.oop

fun main() {
    //사용자정의 클래스를 사용하는 방법
    //객체생성 = 클래스의 인스턴스화 작업
    //정의된 클래스를 실제 프로그램 내부에서 사용하기 위해 메모리에 올려놓는 작업
    val obj1:MyClass = MyClass()
    val obj2 = MyClass() // 객체를 참조하는 변수와 실제 생성되는 객체가 타입이 동일한 경우 참조변수의 타입을 생략할 수 있다.
    println("obj1:$obj1") //주소값이 나오게 됨
    println("obj1:$obj2")

    val obj3:Person = Person()
    obj3.name = "장동건"
    obj3.age = 22
    obj3.telNum = 111111
    println("Person의 데이터:${obj3.name}, ${obj3.age}, ${obj3.telNum}")
    obj3.print()
}
//클래스를 작성하는 방법
class MyClass {

}
class Person {
    //DB의 레코드를 모델링한 클래스인 경우 멤버변수가 DB의 컬럼
    //DB의 데이터를 저장하고 가져오기 위해 setter/getter메소드 필수로 작성
    //멤버변수정의
    var name = ""
    var telNum = 0
    var age = 0
    //멤버메소드 - Person클래스가 갖고 있는 기능(함수와 동일한 방법으로 정의)
    fun print() {
        println("print=>name:$name, age:$age, telNum:$telNum")
    }
}
package com.example.kotlinwork.oop

fun main() {
    val obj1:Customer = Customer()
    obj1.name = "이민호" //Customer클래스에 자동으로 생성되는 setter메소드(setName) 를 호출
    println("성명:${obj1.name}") //Customer클래스에 자동으로 생성되는 getter메소드(getName) 를 호출
    val obj2:Customer = Customer("장동건",20)
    val obj3:Customer = Customer("장동건", 20,"010")
}

//생성자작성 방법 - 1. 기본방법
//생성자는 매개변수 갯수, 매개변수 타입을 다르게 추가해서 여러개를 정의할 수 있다.
//클래스를 정의하면 코틀린 내부에서 자바코드로 변환될때 자동으로 setter/getter메소드가 만들어진다

class Customer {
    var name = ""
    var age:Int = 0
    var telNum = ""
    init {
        //객체가 생성될때 실행해야 하는 기능 - 코틀린에서는 생성자에 멤버변수 초기화를 정의한다.
        println("객체가 생성될때 처리해야 하는 일들을 정의")
    }
    constructor() {
        println("매개변수가 없는 생성자")
    }
    constructor(name:String, age:Int) {
        this.name = name
        this.age = age
        println("매개변수 2개 생성자")
    }
    constructor(name:String, age:Int, telNum:String) {
        this.name = name
        this.age = age
        this.telNum = telNum
        println("매개변수 3개 생성자")
    }
}
package com.example.kotlinwork.oop

fun main() {
    val obj1 = Emp3("이민호",25,10)
    val obj2 = Emp3("BTS")
}
//1. 생성자 정의 - 기본방법
class Emp {
    var name = ""
    var telNum = 0
    var age = 0

    constructor(name: String, telNum: Int, age: Int) {
        this.name = name
        this.telNum = telNum
        this.age = age
    }
}
// 2번째 방법 - 생성자와 같이 만들어짐
class Emp2 constructor(name:String, age:Int, telNum:Int) {

}
// 3번째 방법 = 생성자와 같이 만들어짐
//클래스를 선언하면서 기본생성자를 바로 정의하는 경우 constructor 키워드를 생략할 수 있다.
//기본생성자에 정의하는 매개변수는 자동으로 멤벼변수로 등록된다.
//기본생성자를 정의하면 매개변수 없는 생성자는 제공되지 않는다.
class Emp3(var name:String,var age:Int,val telNum:Int) { //기본생성자
    init {
        println("init코드 실행")
        println("name:$name")
        println("age:$age")
        println("telNum:$telNum")
    }
    //기본생성자 이외에 추가하는 생성자를 보조생성자라고 한다
    //보조생성자에서 기본생성자를 호출할 수 있다.
    //constructor(.......) :this("기본생성자의 매개변수들")
    constructor(name:String):this(name,40,11) {
        println("보조생성자호출")
    }
    //기본생성자를 정의하는 경우 보조 생성자를 정의할 때 반드시 기본생성자를 호출해서 값을 셋팅해야 한다.
    constructor(name:String,age:Int):this(name, age, 10111777){
        this.name = name
        this.age = age
    }
}
package com.example.kotlinwork.oop

fun main() {
    var obj = SubA()
    println("--------------------")

}
//코틀린에서 만드는 클래스는 final클래스이므로 상속을 하기 위해서는 final을 해제 = open 붙이면 됨
//상속할때는 부모클래스 먼저 메모리에 올리고 자식클래스 메모리에 올리는 순으로 해야함.
open class SuperA {
    var superVal = 100
    constructor() {
        println("부모클래스의 생성자")
    }
    open fun superDisplay() {
        println("super클래스의 display()")
    }
}
class SubA : SuperA { //SubA가 SuperA클래스를 상속한다.
    var subVal = 1000
    constructor():super() { //SubA의 매개변수 없는 생성자를 호출하기 전에 부모클래스 생성자를 호출
        println("자식클래스의 생성자")
    }
    fun subDisplay() {
        println("sub클래스의 display()")
    }
    //메소드 오버라이딩 - 1. override 키워드를 메소드 선언부에 추
    //                  2. 오버라이드 하려는 부모클래스의 선언부에 open을 추가한다
    //                  3. 부모클래스의 메소드를 재정의 하면 부모클래스의 메소드가 호출되지 않고 재정의된 메소드가 호출된다.
    override fun superDisplay() {
        println("sub클래스에서 재정의된 메소드")
    }
}

 

댓글

Designed by JB FACTORY