Kotlin 기본 문법
- 프로그래밍/Kotlin
- 2022. 4. 27.
안드로이드 스튜디오에서 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클래스에서 재정의된 메소드")
}
}