📌 유튜브 강의 - 코틀린 끝내기
코틀린 끝내기
www.youtube.com
위 강의를 들으며 Kotlin의 기초를 공부하고, 관련 내용을 블로그에 정리해보려 한다.
안드로이드
✏️안드로이드란?
: 모바일 기기를 제어하는 리눅스 기반의 운영체제
✏️왜 안드로이드를 배워야 할까?
- 오픈소스
- 누구든 코드를 볼 수 있고 접근 가능!
- 기기의 호환성에 맞게 자유롭게 수정 가능!
- 다양한 생태계 존재
- Android TV, Wear OS, Android Auto, Android Things ...
- 모바일에만 국한되지 않음
- 풍부한 리소스 & 검증된 라이브러리
- 특정 운영 체제나 장비 필요 X
- iOS의 경우는 맥을 써야 함
- 안드로이드는 맥, 윈도우, 리눅스 전부 가능
코틀린
✏️코틀린이란?
: JVM에서 동작하는 정적 타입 프로그래밍 언어
- Java에서 발생하는 문제들을 해결하기 위한 목적으로 만들어져서 실용적이고 간결한 특징을 가짐
- 2017년 구글 I/O에서 안드로이드의 공식 언어로 코틀린을 추가함
✏️왜 코틀린을 써야 할까?
- 간결성
- 누구든 코드를 볼 수 있고 접근 가능!
- 기기의 호환성에 맞게 자유롭게 수정 가능!
- 더 안전한 코드
- Java에 있는 NullPointerException과 같은 일반적인 프로그래밍 실수 방지
- 실행 전, 컴파일 시점에 에러를 잡아줌
- Java와 100% 호환 가능성
- 한 프로젝트 내에서 Java와 Kotlin을 섞어서 사용해도 괜찮음!
개발 환경 설정
⚙️Android Studio 설치하기
Download Android Studio & App Tools - Android Developers
Android Studio provides app builders with an integrated development environment (IDE) optimized for Android apps. Download Android Studio today.
developer.android.com
New Project를 생성해주면 준비 완료.
Kotlin 문법
✏️ 함수
- return 타입
- java의 경우에는 return 타입을 앞에 써주지만, Kotlin은 뒤쪽에 써준다.
Unit
: return이 없는 경우. 생략 가능.- return이 있는 경우에는 타입 생략 불가
- 변수
- 이름을 먼저 쓰고, 타입을 뒤에 쓴다.
- 변수 타입은 첫 글자를 대문자로 쓴다.
// 코틀린이 처음 시작되는 함수 (엔트리 함수)
fun main(){
helloWorld() // Hello World!
println(add(4, 5)) // 9
}
// 1. 함수
fun helloWorld() {
println("Hello World!")
}
fun add(a : Int, b : Int) : Int {
return a+b
}
✏️ val vs var
- val (value)
- 변하지 않는 값. 상수
- var (variable)
- 변할 수 있는 수
// 2. val vs var
fun hi() {
val a : Int = 10
var b : Int = 9
// a = 100 // (X) 상수 값을 바꿀 수 없음!
b = 100 // (O)
val c : Int = 10 // 타입(Int) 생략 가능! - 자동타입추론(type inference)
val d = 10
var e : Int = 10 // 타입(Int) 생략 가능! - 자동타입추론(type inference)
var f = 10
var name : String = "yudaeng" // 타입(String) 생략 가능! - 자동타입추론(type inference)
var g : String // 값을 바로 할당하지 않을 거라면 타입은 지정해줘야 함
}
✏️ String template
- ${ }
- 변수를 출력하고 싶을 때 사용
- { } 생략 가능하지만, 생략하는 경우에는 뒤에 오는 단어 꼭 띄어쓰기 해줘야 함
- '$' 문자를 쓰고 싶을 때는 앞에
\
(back slash) 써주기
fun main(){
// 3. String Template
val name = "yudaeng"
val lastName = "Heo"
println("my name is ${name} I'm 20") // my name is yudaneg I'm 20
println("my name is ${name + lastName}") // my name is yudanegHeo
println("this is 2\$aa") // this is 2$aa
/**
* 여러 줄 주석
*/
}
✏️ 조건식
if
(조건) 참일 때 결과else
거짓일 때 결과- Kotlin에는 삼항 연산자가 없기 때문에 이런 식으로 표현
- when
- expression(표현식) : 값을 만들어서 반환하면 expression
🌟Kotlin의 모든 함수는 expression이다!! (아무것도 반환하지 않더라도 사실Unit
을 만들어서 반환함) - statement(문) : 값을 반환하지 않고 무언가 명령을 수행하면 statement
🌟Java는 반환형이void
일 경우 statement
=> Kotlin의 if-else는 expression, Java의 if-else는 statement
- expression(표현식) : 값을 만들어서 반환하면 expression
package com.example.a0718_testapplication
// 코틀린이 처음 시작되는 함수 (엔트리 함수)
fun main(){
checkNum(1) // this is 1
// b : 1
// okay
}
// 4. 조건식
// 1-1) if-else
fun maxBy(a : Int, b : Int) : Int {
if(a > b) {
return a
} else {
return b
}
}
// 1-2) 같은 내용 간결한 코드
fun maxBy2(a : Int, b : Int) : Int = if(a > b) a else b
// 2) when
fun checkNum(score : Int) {
// 2-1)
when(score) {
0 -> println("this is 0")
1 -> println("this is 1")
2, 3 -> println("this is 2 or 3") // 복수 가능
else -> println("I don't know") // 어떤 케이스에도 해당되지 않는 경우 (여기서는 생략 가능)
}
// 2-2) expression으로 사용되는 경우
var b : Int = when(score) {
1 -> 1
2 -> 2
else -> 3 // 여기서는 생략 불가
}
println("b : ${b}")
// 2-3) 범위
when(score) {
in 90..100 -> println("You are genius")
in 10..80 -> println("not bad")
else -> println("okay")
}
}
✏️ Array & List
- Array (배열)
- 생성될 때 메모리가 할당됨. 길이 고정.
- List
- List : 수정이 불가능한 리스트
- list는 array와 다르게 '인터페이스'이기 때문에 값을 가져오는 것은 가능하지만, 변경은 불가능
- MutableList : 수정이 가능한 리스트
- set, remove 등의 메소드가 구현되어 있기 때문에 수정도 가능
- 대표적인 것인 arrayList
- List : 수정이 불가능한 리스트
// 5. Array and List
// Array
fun array() {
val array : Array<Int> = arrayOf(1, 2, 3) // 배열 초기화 arrayOf
val list :List<Int> = listOf(1, 2, 3) // 리스트 초기화 listOf
val array2 :Array<Any> = arrayOf(1, "d", 3.4f) // 타입 여러가지 섞어서 넣을 수도 있음
val list2 :List<Any> = listOf(1, "d", 11L)
array[0] = 3 // 배열 값을 바꿀 수 있음
// list[0] = 2 // immutable이기 때문에 값을 바꿀 수 없음
var result :int = list.get(0) // list는 interface이기 때문에 값을 가져오는 것만 가능. 수정X
val arrayList :ArrayList<Int> = arrayListOf<Int>()
arrayList.add(10)
arrayList.add(20) // 리스트에 들어있는 값들은 바뀌지만, 리스트의 주소값 자체는 바뀌지 않기 때문에 val 써도 괜찮다!!
// arrayList = arrayListOf() // 이렇게 재할당은 불가.
}
✏️ 반복문
- for
in
: 배열/리스트 안에 있는 원소들 꺼내오기withIndex()
: index도 함께 활용 가능
- 범위
- A
..
B : A 이상 B 이하 - A
until
B : A 이상 B 미만 - A
downTo
B : A 이하 B 이상 step
: 몇 칸씩 증가/감소 할 것인지
- A
- while
// 6. For / While
fun forAndWhile() {
val students :ArrayList<String> = arrayListOf("yudaeng", "james", "jenny", "jennifer")
for (name:String in students) {
println("${name}")
}
var sum:Int = 0
for(i:Int in 1..10 step 2) {
sum += i
}
println(sum)
sum = 0
for(i:Int in 1 until 10) {
sum += i
}
println(sum)
sum = 0
for(i:Int in 10 downTo 1) {
sum += i
}
println(sum)
var idx = 0
while(idx < 10) {
println("index : ${idx++}")
}
for((index:Int, name:String) in students.withIndex()){
println("${index+1}번째 학생 : ${index + 1}")
}
}
✏️ NonNull & Nullable (🌟Java와 다른 Kotlin의 큰 특징)
Java는 런타임에서만 null이 잡히기 때문에 NullPointerException 발생
Kotlin은 런타임이 아닌 컴파일 시점에서 null을 잡아준다!!
- NonNull
- null 값을 허용하지 않는 타입
- Nullable
- null 값을 허용하는 타입
- ? 로 표시
- 연산자
- ?.
- null safe 연산자
- 앞의 변수가 null이 아닐때만 오른쪽 함수가 수행되고 null이면 null을 반환
- ?:
- Elvis 연산자
- 왼쪽 변수가 null이 아니면 그 객체의 값이 리턴되고, null이면 ?:의 오른쪽 값을 리턴
- !!
- null이 아님을 보장함. 강제 not null 처리.
- 잘못 사용하면 NullPointerException 발생할 수도. 정말 확실한 경우에만 사용하기.
- ?.
// 7. Nullable / NonNull
fun nullcheck(){
var name = "yudaeng"
var nullName : String? = null // nullable. 이때는 타입 생략하면 안됨 (생략하면 nonnull)
var nameInUpperCase :String = name.toUpperCase()
var nullNameInUpperCase :String? = nullName?.toUpperCase() // null이 아니면 대문자로 변환, null이면 null 반환
// ? : 엘비스 연산자
val lastName : String? = null
val fullName : String = name + " " + (lastName?:"No lastName") // lastName이 null인 경우 "No lastName" 반환
println(fullName)
}
fun ignoreNulls(str: String?) {
// !! : null이 아님을 보장함. 정말정말 확실한 경우에만 사용하기!! 잘못하면 NullPointerException 발생.
val mNotNull : String = str!! // 내가 컴파일러에게 이건 null일 리가 없다! 라고 알려주는 것
val upper :String = mNotNull.toUpperCase() // ? 쓰지 않아도 수행 가능
val email :String? = "XXX@nana.com"
email?.let{ // email이 null이 아니면 receiver 객체인 email을
println("my email is ${email}") // 여기(람다식 내부)로 옮겨줌 => null이면 여기서 사용되지 않음!!
}
}
✏️ 클래스
package com.example.a0718_testapplication
open class Human constructor(val name:String = "Anonymous") { // 주생성자
// 부생성자 - 항상 주생성자의 위임을 받아야 한다!
constructor(name:String, age:Int) :this(name){
println("My name is ${name}, ${age}years old")
}
// 인스턴스 생성 시 실행할 내용
init {
println("New human has been born!!")
}
// val name = "yudaeng"
// val name :String = name // 생성자로 사용한 방법.
fun eatingCake() {
println("This is so YUMMMYYYY~~~~")
}
open fun singASong(){
println("lalala")
}
}
// 상속
/**
* Kotlin에서는 클래스가 기본적으로 final이라 같은 파일 내에 있더라도 그냥 상속은 불가.
* 상속할 class를 open 해줘야 한다!
* 함수도 마찬가지로 open 해줘야 한다!
*/
class Korean :Human() {
override fun singASong(){
super.singASong()
println("랄랄라")
}
}
fun main() {
val human = Human("doongdang") // new 할 필요 없음
val stranger = Human() // default 값으로 "Anonymous"를 줬기 때문에 기본 생성자도 사용 가능
human.eatingCake() // This is so YUMMMYYYY~~~~
val mom = Human("mommy",50) // My name is mommy, 50years old
println("this human's name is ${human.name}") // this human's name is doongdang
println("this human's name is ${stranger.name}") // this human's name is Anonymous
println("-----------------------------------------")
val korean = Korean() // New human has been born!!
korean.singASong() // lalala
// 랄랄라
}