들어가기 앞서
코틀린이은 2017년도에 안드로이드 공식 언어로 채택된 언어이다. JVM 기반 언어이며 자바와 유사하지만 더 간결한 문법과 다양한 기능을 제공해준다. 현재 주 언어는 자바를 사용하지만 시간이 날때마다 틈틈히 새로운 기술을 익혀보고자 인프런에 코틀린 기본 강의를 듣고 기본 문법을 정리한다. 그리고 자바와는 어떤 차이가 있는지도 더불어 정리한다.
코틀린 기본문법
패키지 정의
- 패키지 정의는 파일 최상단에 위치함(자바와 동일)
- 자바와 다른점은 디렉터리와 패키지를 꼭 일치시키지 않아도 된다.
임포트
- 자바와 똑같음
함수 정의(자바와 많이 다름)
- 함수는 fun 키워드로 정의함
- 제일 마지막에 리턴 타입이 나오고 생략도 가능한 경우도 있다.
- 식으로 표현된 경우는 return을 생략 가능하다.
//형식
fun sum ( 인자1 : 자료형1, 인자2 : 자료형2, ...) : 반환자료형
//블럭으로 표현된 경우
fun sum(a: int, b: int): int {
return a + b
}
//식으로 표현된 경우 (위와 동일함)
fun sum(a: int, b: int) = a +b
함수 정의 리턴 값이 없는 경우
- Unit(Object)로 리턴을 한다 (자바의 void와 동일하고 Unit은 하나의 Object이다)
- 아무것도 적지 않으면 Unit 생략 가능
// 리턴값이 없는 경우 Unit 선언
fun printKotlin(): Unit {
println("hello")
}
// 생략하는 경우
fun printKotlin() {
println("hello")
}
지역 변수 정의
- val : 읽기전용변수 (자바의 final과 유사), 값의 할당이 1회만 가능하다.
- var : 쓰고읽고가능한변수
//val
val a int = 1 // 즉시 할당(초기화)하는 경우
val b =2 // 타입 추론을 통해 int
val c: int // val을 초기화 필요하므로 컴파일 시 오류 발생
c = 3 // 읽기 전용이므로 이렇게 추후의 값을 할당하는 경우도 컴파일 오류
//var
var x = 5
x += 1 // 추후 값 변경 가능함.
기본 자료형 - 숫자형
Double / Float / Long / Int / Short / Byte
기본 자료형 - 문자형
String / Char
문자열 여러줄 표현
- """ 으로 문장의 앞과 뒤를 감싸기만 하면 개행이나 공백을 포함한 모든 문자를 그대로 표현해준다.
문자열 템플릿
val msg = "안녕하세요"
println(msg + "!!") -> 자바
println("${msg} !!") -> 코틀린
배열
- 배열의 타입은 코틀린에서 Array이다. Array 타입을 충분히 유추가 가능하다면 생략 가능하다.
- 배열의 생성은 arrayOf()라는 함수를 사용하여 생성과 초기화를 한번에 할 수 있다.
val num1 : Array<Int> = arrayOf(1,2,3,4,5)
val num2 = arrayOf(1,2,3,4,5)
주석
- 자바와 자바스크립트와 동일함
- // -> 한줄 주석
- /* */ -> 여러 줄 주석
- 블럭 코맨트가 자바와 다르게 중첩을 허용함
/*
/* */
*/
문자열 템플릿
- String Interpolation (문자열 보간법)
- 자바에서처럼 스트링빌더나 + 연산자를 통하지 않고 핸들링 가능
var a = 1
// simple name in template:
val s1 = "a is $a"
a = 2
//arbitrary expression in template:
val s2 = "${s1.replace("is", "was")}, but now is $a"
조건문
fun maxOf(a: int, b: int): int {
if (a > b) {
return a
} else {
return b
}
}
조건식으로 변경한 조건문
fun maxOf(a: int, b: int) = if (a > b) a else b
nullable(중요!!!)
- 값이 null일 수 있는 경우 타입에 nullable 마크를 명시해야함
fun parseInt(str: String): int? {
// 정수가 아닌 경우 null을 리턴
}
- ?(nullable 마크) 을 적어줘서 null이 리턴될 수 있음을 명시한다.
- ? 을 적지 않고 null을 리턴하는 경우 컴파일시 오류가 난다.
- nullable 타입의 변수를 접근할 때는 반드시 null 체크를 해야한다.
fun printProduct(arg1 : String, arg2: String) {
val x: int? = parseInt(arg1)
val y: int? = parseInt(arg2)
if(x != null && y != null) {
println(x * y)
} else {
println("either '$arg1' or '$arg2' is not a number")
}
}
- 이렇게 nullable을 지원하므로 안전하게 코딩이 가능
자동 타입 변환
- 타입 체크만 해도 자동으로 타입 변환이 됨
- Any는 자바에서의 Object와 같이 최상위 타입이다.
fun getStringLength(obj: Any): int? {
if(obj is String) { // 여기서 is는 instanceOf와 비슷하다. 타입 비교시 이용
//'obj'가 자동으로 String 타입으로 변환 됨
return obj.length
}
return null
}
while loop
- 자바와 같다고 봐도 됨
val items = listOf("apple", "banana", "kiwi")
var index = 0
while (index < items.size) {
println("item at $index is ${items[index]}")
index++
}
when expression
- 자바의 switch case와 비슷해 보이지만 좀 더 많은 타입을 지원함
- 자바에서는 정수나 스트링 정도 이지만 when에서는 많은 타입 지원
fun describe(obj: Any): String =
when (obj) {
1 -> "One" // obj가 1이면 One
"Hello" -> "Greeting" // Hello 이면 Greeting ...
is Long -> "Long"
!is String -> "Not a string"
else -> "Unknown"
}
- 이것을 자바로 동일하게 구현한다면 훨씬 코드가 길어지고 복잡해 질것이다.
ranges
- in 연산자를 이용해서 숫자 범위를 체크 가능
val x = 3
if (x in 1..10) { // 1~10까지 범위를 in 을 통해 줄 수 있다. -> 1과 10사이에 3이 있다면 참
println("hello")
}
- range를 이용한 for loop
for (x in 1..5) { // 1~5까지 반복
print(x)
}
for 반복문 - 숫자 반복하기
- 1..10까지의 합 구하기
var sum = 0
for (i in 1..10) {
sum += i
}
- 1..10 사이에서 홀수의 합을 구하기
var sum = 0
for (i in 1..10 step 2) {
sum += i
}
- 10 ~ 0 까지 3씩 감소하면서 출력하기
for (i in 10 downTo 0 step 3) {
println("i is ${i},,")
}
Collections
- 컬렉션도 in 으로 loop 가능
- foreach 와 동일함
val items = listOf("apple", "banana", "kiwi")
for (item in items) {
println(item)
}
- in으로 해당 값이 collection에 포함되는지 체크 가능
val items = setOf("apple", "banana", "kiwi")
when {
"orange" in items -> println("juicy") // items 에 orange가 포함되는지 체크하는 것
"apple" in items -> println("apple is fine too")
}
- 람다식을 이용해서 컬렉션에 filter, map 등의 연산 가능 (자바의 stream과 비슷)
val fruits = listOf("banana", "avocado", "apple", "kiwi")
fruits
.filter{ it startsWith("a") } // 여기서 it 이란 list에 있는 값들이 들어오는 변수
.sortedBy { it }
.map { it.toUpperCase() }
.forEach { println(it) }
접근제한자
- public
- private
- internal : 같은 모듈 내에서만 사용 가능
ex ) app 모듈 내에 tv, phone, watch 모듈이 있고, app 모듈 내에 Fruit 클래스 내에 internal로 선언한 필드 weight이 있다면, tv, phone, watch 모듈에서 모두 weight 필드에 접근 가능하다.
- protected : 상속받은 클래스에서 사용할 수 있다.
클래스 상속
- 코틀린에서 클래스는 기본적으로 상속이 금지
- 상속을 가능하도록 허용하려면 open 키워드를 클래스 선언 앞에 추가해야함.
open class Fruit{}
class Apple : Fruit() {}
내부 클래스
- 다른 언어들에서와 같이 클래스 내부에 클래스를 선언하는 것을 내부클래스라고 함
- 내부 클래스 선언시 inner 키워드를 사용
class Student {
var name : String = "Jordan"
init{
println("My name is $name")
}
inner class Personality {
fun doSomething() : Unit {
name += ", He is Chicago Bulls No.23 Basketball Start"
println(name)
}
}
}
val student : Student = Student()
student.Personality().doSomething()
추상클래스
-
'Jave & Kotlin' 카테고리의 다른 글
Java - 간단한 게시판 구현을 통한 직렬화(Serialization) 이해하기(1) - 클래스 생성과 serialVersionUID 개념 및 설정방법 (0) | 2021.12.23 |
---|---|
Java - 직렬화(Serialization)란? (implement serializable) (0) | 2021.12.22 |
JAVA - final, static, final static 키워드 상황별 정리 (0) | 2021.12.17 |
JAVA - Interface 관련 정리 및 JAVA 8에서의 Default, Static (0) | 2021.12.15 |
자바의 정석 - 자바 기본기 정리하기 (12)쓰레드 (0) | 2021.11.25 |
댓글