Kotlin 소개
Kotlin은 JetBrains에서 개발한 현대적인 프로그래밍 언어입니다. 주로 JVM (Java Virtual Machine) 위에서 동작하며, Android 개발을 포함한 다양한 애플리케이션에서 널리 사용됩니다. 간결한 문법, 강력한 타입 시스템, Null-safe 기능 등 여러 가지 장점을 가지고 있어 많은 개발자들 사이에서 인기를 끌고 있습니다.
간결한 문법
Kotlin의 문법은 매우 간결하여 코드의 가독성과 유지보수성이 뛰어납니다. 예를 들어, Java에서 객체를 출력하는 코드를 비교해 보면 쉽게 알 수 있습니다.
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
public class Main {
public static void main(String[] args) {
Person person = new Person("John", 30);
System.out.println("Name: " + person.getName());
System.out.println("Age: " + person.getAge());
}
}
Kotlin에서는 다음과 같이 작성할 수 있습니다.
class Person(val name: String, val age: Int)
fun main() {
val person = Person("John", 30)
println("Name: ${person.name}")
println("Age: ${person.age}")
}
Null 안전성
Kotlin은 NullPointerException을 방지하기 위해 강력한 Null-safe 기능을 제공합니다. 변수 선언 시 기본적으로 Null을 허용하지 않으며, Null이 필요한 경우에는 물음표(?)를 사용하여 선언합니다.
var name: String = "John" // Non-nullable 변수
var nullableName: String? = null // Nullable 변수
fun printName(name: String?) {
if (name != null) {
println("Name is $name")
} else {
println("Name is null")
}
}
fun main() {
printName(name) // 출력: Name is John
printName(nullableName) // 출력: Name is null
}
데이터 클래스
Kotlin에서 데이터 클래스는 주로 데이터 저장을 목적으로 사용되며, get/set 메서드, equals(), hashCode(), toString() 등의 메서드를 자동으로 생성해 줍니다.
data class User(val name: String, val age: Int)
fun main() {
val user = User("Alice", 29)
println(user)
}
변수와 데이터 타입
2.1 변수 선언
Kotlin에서 변수는 `val`과 `var` 키워드로 선언합니다. `val`은 값을 변경할 수 없는 불변 변수(immutable)를 선언할 때 사용하고, `var`는 값을 변경할 수 있는 가변 변수(mutable)를 선언할 때 사용합니다.
“`kotlin
val immutableVariable: String = “This is immutable”
var mutableVariable: Int = 10
“`
변수 타입은 Kotlin의 타입 추론 기능 덕분에 생략할 수도 있습니다.
“`kotlin
val inferredVariable = “Type is inferred as String”
var anotherInferredVariable = 20
“`
2.2 기본 데이터 타입
Kotlin에서는 다양한 기본 데이터 타입을 지원합니다. 대표적인 타입은 다음과 같습니다:
– `Int`: 정수
– `Double`: 실수
– `Boolean`: 참/거짓
– `Char`: 문자
– `String`: 문자열
기본 데이터 타입을 사용하는 예제는 다음과 같습니다:
fun main() {
val intVar: Int = 42
val doubleVar: Double = 3.14
val booleanVar: Boolean = true
val charVar: Char = 'A'
val stringVar: String = "Hello, Kotlin!"
println("Int value: $intVar")
println("Double value: $doubleVar")
println("Boolean value: $booleanVar")
println("Char value: $charVar")
println("String value: $stringVar")
}
2.3 Null 처리
Kotlin은 안전한 Null 처리를 위해 Null 안전성을 언어 차원에서 지원합니다. 변수를 선언할 때 타입 뒤에 `?`를 붙이면 Null을 허용할 수 있습니다. Null 값을 다룰 때는 안전한 호출 연산자(`?.`), 엘비스 연산자(`?:`), 그리고 `!!` 연산자 등을 사용할 수 있습니다.
fun main() {
var nullableString: String? = "I can be null"
nullableString = null
// Safety call operator
println(nullableString?.length) // Output: null
// Elvis operator
val length = nullableString?.length ?: -1
println(length) // Output: -1
// Not-null assertion operator
try {
println(nullableString!!.length)
} catch (e: NullPointerException) {
println("Caught a NullPointerException")
}
}
조건문과 반복문
3.1 조건문
Kotlin에서는 다양한 조건문을 사용할 수 있습니다. 대표적인 조건문으로는 `if`와 `when`이 있습니다.
if 조건문
기본적인 `if` 조건문 사용 예제입니다:
fun main() {
val a = 10
val b = 20
if (a > b) {
println("a is greater than b")
} else if (a < b) {
println("a is less than b")
} else {
println("a is equal to b")
}
}
`if`를 표현식으로 사용할 수도 있습니다:
fun main() {
val max = if (a > b) a else b
println("The maximum value is $max")
}
when 조건문
`when`은 좀 더 강력한 조건문으로, 여러 조건을 처리할 수 있습니다:
fun main() {
val number = 3
when (number) {
1 -> println("One")
2, 3 -> println("Two or Three")
in 4..10 -> println("Between Four and Ten")
else -> println("Unknown number")
}
// when을 표현식으로 사용
val result = when {
number % 2 == 0 -> "Even"
else -> "Odd"
}
println("The number is $result")
}
3.2 반복문
Kotlin에서는 `for`와 `while` 반복문을 사용할 수 있습니다.
for 반복문
기본적인 `for` 반복문 사용 예제입니다:
fun main() {
val items = listOf("apple", "banana", "kiwi")
for (item in items) {
println(item)
}
for (index in items.indices) {
println("Item at $index is ${items[index]}")
}
}
while 반복문
기본적인 `while`과 `do-while` 반복문 사용 예제입니다:
fun main() {
var x = 5
while (x > 0) {
println(x)
x--
}
x = 0
do {
println("x is now $x")
x++
} while (x < 5)
}
함수와 람다
4.1 함수 정의
Kotlin에서 함수 정의는 `fun` 키워드를 사용합니다. 함수는 기본적으로 반환 타입과 매개변수를 가질 수 있습니다.
기본적인 함수 정의 예제:
fun main() {
println(sum(3, 4))
println(maxOf(5, 10))
}
fun sum(a: Int, b: Int): Int {
return a + b
}
fun maxOf(a: Int, b: Int): Int {
return if (a > b) a else b
}
단일 표현식 함수의 경우 return 문 대신 표현식을 사용할 수 있으며, 반환 타입을 추론할 수 있습니다:
fun sum(a: Int, b: Int) = a + b
4.2 고차 함수
고차 함수는 함수를 매개변수로 받거나 반환하는 함수입니다.
고차 함수의 예제:
fun main() {
val result = higherOrderFunc(5, 10, ::sum)
println("The result is $result")
val lambdaResult = higherOrderFunc(5, 10) { a, b -> a * b }
println("The lambda result is $lambdaResult")
}
fun higherOrderFunc(a: Int, b: Int, operation: (Int, Int) -> Int): Int {
return operation(a, b)
}
fun sum(a: Int, b: Int): Int {
return a + b
}
4.3 람다식
람다식은 익명 함수로, 코드를 간결하게 작성할 수 있는 방법입니다. 중괄호 `{}` 안에 인자 리스트와 표현식을 작성합니다.
기본적인 람다식의 예제:
fun main() {
val sumLambda: (Int, Int) -> Int = { x, y -> x + y }
println(sumLambda(3, 4))
val items = listOf(1, 2, 3, 4, 5)
val doubledItems = items.map { it * 2 }
println(doubledItems)
val filteredItems = items.filter { it % 2 == 0 }
println(filteredItems)
}
람다식을 사용하는 또 다른 예제:
fun main() {
val greeting: (String) -> Unit = { name -> println("Hello, $name!") }
greeting("Kotlin")
val multiplyLambda: (Int, Int) -> Int = { a, b -> a * b }
println(multiplyLambda(3, 5))
}
클래스와 객체지향 프로그래밍
5.1 클래스 선언
Kotlin에서의 클래스 선언은 `class` 키워드를 사용해 정의할 수 있습니다.
기본적인 클래스 선언 예제:
fun main() {
val person = Person("John", 25)
println(person.name)
println(person.age)
person.introduce()
}
class Person(val name: String, var age: Int) {
fun introduce() {
println("Hi, I'm $name and I'm $age years old.")
}
}
하나의 파일에 여러 클래스를 정의하는 경우:
fun main() {
val rectangle = Rectangle(5.0, 3.0)
println("Area: ${rectangle.area()}")
val circle = Circle(4.0)
println("Area: ${circle.area()}")
}
class Rectangle(val width: Double, val height: Double) {
fun area() = width * height
}
class Circle(val radius: Double) {
fun area() = Math.PI * radius * radius
}
5.2 상속
Kotlin에서 클래스 상속은 `:` 기호를 사용합니다. 기본적으로 모든 클래스는 기본 상속금지 상태이므로, 상속을 허용하려면 `open` 키워드를 사용해야 합니다.
상속의 예제:
fun main() {
val dog = Dog("Buddy", 5)
dog.sound()
}
open class Animal(val name: String, val age: Int) {
open fun sound() {
println("Some generic animal sound")
}
}
class Dog(name: String, age: Int) : Animal(name, age) {
override fun sound() {
println("Bark")
}
}
5.3 인터페이스
인터페이스는 클래스가 구현해야 하는 메서드와 프로퍼티를 정의할 수 있습니다. `interface` 키워드를 사용해 정의합니다.
인터페이스 예제:
fun main() {
val myCar = Tesla()
println("CarName: ${myCar.name}")
myCar.startEngine()
}
interface Car {
val name: String
fun startEngine()
}
class Tesla : Car {
override val name = "Tesla Model S"
override fun startEngine() {
println("Tesla engine started")
}
}
5.4 데이터 클래스
데이터 클래스는 주로 데이터를 저장하는 용도로 사용하는 클래스입니다. `data` 키워드를 사용해 정의합니다.
데이터 클래스의 예제:
fun main() {
val user = User("Alice", 30)
println(user)
val copiedUser = user.copy(age = 31)
println(copiedUser)
val (name, age) = user
println("Name: $name, Age: $age")
}
data class User(val name: String, val age: Int)