반응형
들어가면서
`변수, 타입, 조건문, 반복문, List 등등`
이러한 기초 문법을 1편에서 익히고 왔다.
2편에서는 웹개발에 필요한 문법들 위주로 더 설명한다.
함수
fun main() {
println(sum(10, 20))
}
fun sum(a: Int, b: Int): Int {
return a + b
}
fun sum(a: Int, b: Int): Int = a + b
fun sum(a: Int, b: Int) = a + b
함수 내부가 1개의 line 일 때의 축약 표현도 있다.
fun main() {
println(sum(10, 20)) // 기본값 사용
println(sum(b = 10, a = 20)) // 명명된 인자 사용
}
fun sum(a: Int, b: Int, c: Int = 0) = a + b + c // c에 기본값 0 설정
- `fun sum(a: Int, b: Int, c: Int = 0)`
- 코틀린에서는 함수의 매개변수에 기본값을 설정할 수 있다.
- 함수 호출 시 c 값을 생략하면 자동으로 0이 사용된다.
- 자바에서는 함수 매개변수에 기본값을 설정할 수 없기 때문에, 기본값을 사용하려면 `메서드 오버로딩`을 사용해야 했다.
- `sum(b = 10, a = 20)`
- `명명된 인자`를 사용하면, 함수의 매개변수를 순서와 상관없이 지정할 수 있다.
- 이렇게 하면 함수 호출 시 가독성이 좋아지고, 특정 인자만 명확하게 지정할 수 있다.
Class
fun main() {
val john = Person("John", 25)
println("name: ${john.name}")
// setter 사용하지 않아도 직접 값 변경 가능
john.age = 26
println("age: ${john.age}")
}
class Person(
val name: String,
var age: Int,
)
- 코틀린은 val과 var 프로퍼티에 대해 자동으로 getter와 setter를 생성한다.
- val name은 자동으로 `getter만` 생성하고, var age는 `getter와 setter를 모두` 생성한다.
- `john.name`은 getter를 통해 name 값을 가져오고,
- `john.age = 26`은 setter를 통해 age 값을 변경한다.
fun main() {
val john = Person("John", 25)
// println("name: ${john.name}") // 프로퍼티 접근 불가능
// setter 사용하지 않아도 직접 값 변경 가능
john.age = 26
println("age: ${john.age}")
}
class Person(
private val name: String,
var age: Int,
)
name을 생성자에서 전달만 하고, name을 접근하지 못하게 하려면 class 정의에서 private 접근제어자를 추가한다.
Enum class
fun main() {
val color = Color.RED
when (color) {
Color.RED -> println("The color is Red.")
Color.GREEN -> println("The color is Green.")
Color.BLUE -> println("The color is Blue.")
}
}
enum class Color {
RED,
GREEN,
BLUE
}
Color는 `열거형 클래스`이며, RED, GREEN, BLUE 세 가지 상수를 정의하고 있다.
data class
fun main() {
val john1 = Person("John", 20)
val john2 = Person("John", 20)
println(john1) // 객체의 문자열 표현
println(john2) // 객체의 문자열 표현
println(john1 == john2) // 객체 간 동등성 비교
}
data class Person(
val name: String, // 읽기 전용 프로퍼티
var age: Int // 읽기 및 쓰기 가능 프로퍼티
)
데이터 클래스는 객체를 데이터 보관 용도로 사용하려는 경우 유용하다. 이를 통해 자동으로 아래의 `주요 메서드들이 제공된다.`
- `toString()`: 객체의 문자열 표현을 반환한다. 예를 들어, println(john1)은 "Person(name=John, age=20)"와 같은 형식으로 출력된다.
- `equals()`: 객체의 내용을 비교하여 동등성 비교를 수행한다. john1 == john2는 두 객체의 name과 age가 같으므로 true를 반환한다.
- `hashCode()`: 객체의 해시 코드를 생성한다. 데이터 클래스는 이를 자동으로 생성해준다.
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{name='" + name + "', age=" + age + '}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return age == person.age && Objects.equals(name, person.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}
위의 자바 코드와 비교하면, 코틀린의 데이터 클래스는 반복적인 코드를 줄이고, 더 명확하고 간결한 코드를 작성할 수 있게 도와준다.
getter, setter
fun main() {
val john = Person1("John", 20)
// john.hobby = "독서" // 불가능
println(john.hobby) // "취미 : 축구" 출력
}
class Person1(
val name: String, // 읽기 전용 프로퍼티
var age: Int // 읽기 및 쓰기 가능 프로퍼티
) {
var hobby = "축구"
private set // 외부에서 `hobby`를 변경할 수 없도록 설정
get() = "취미 : $field" // 커스텀 게터를 사용하여 "취미 : 값" 형식으로 반환
init {
println("init") // 객체가 생성될 때 실행되는 초기화 블록
}
fun some() {
hobby = "농구" // 클래스 내부에서는 `hobby` 프로퍼티를 변경할 수 있음
}
}
각 라인의 주석을 보면서 이해할 수 있겠다.
상속 extends
fun main() {
}
abstract class Animal {
open fun move() {
println("이동")
}
}
class Dog : Animal() {
override fun move() {
println("껑충")
}
}
class Cat : Animal() {
override fun move() {
println("살금")
}
}
- `추상 클래스(abstract class)`는 공통된 기능을 여러 클래스에서 공유할 수 있도록 만든다.
- 코틀린에서는 `open` 키워드를 사용해 메서드 오버라이딩을 허용한다.
- 오버라이딩을 통해 자식 클래스는 부모 클래스의 메서드를 재정의하여 고유한 동작을 가질 수 있다.
interface
interface Drawable {
fun draw()
}
abstract class Animal {
open fun move() {
println("이동")
}
}
class Dog : Animal(), Drawable {
override fun move() {
println("껑충")
}
override fun draw() {
TODO("Not yet implemented")
}
}
class Cat : Animal() {
override fun move() {
println("살금")
}
}
`Drawable 인터페이스`는 추상 메서드 draw()를 선언하고 있다.
인터페이스는 클래스에게 특정 `메서드의 구현을 강제`하는 역할을 한다.
인터페이스와 추상 클래스의 차이
특징 | 인터페이스 | 추상클래스 |
다중 상속 | 다중 구현 가능 (여러 인터페이스 구현 가능) | 단일 상속만 가능 (하나의 클래스만 상속) |
기능 확장 | 특정 기능을 강제하고 여러 클래스에 동일한 기능 제공 | 공통적인 기본 기능을 제공하고 상속을 통해 기능 확장 |
상태와 행위 | 행위(메서드) 정의에 초점, 상태(필드) 가질 수 없음 | 상태(필드)와 행위를 모두 가질 수 있음 |
타입 체크 is
fun main() {
val dog: Animal = Dog()
val cat = Cat()
if (dog is Dog) { // 타입 체크 is
println("멍멍이")
}
}
interface Drawable {
fun draw()
}
abstract class Animal {
open fun move() {
println("이동")
}
}
class Dog : Animal(), Drawable {
override fun move() {
println("껑충")
}
override fun draw() {
TODO("Not yet implemented")
}
}
class Cat : Animal() {
override fun move() {
println("살금")
}
}
강제 타입 변환 as
interface Drawable1 {
fun draw() {
println("Drawing")
}
}
interface Printable {
fun print() {
println("Printing")
}
}
class Document : Drawable1, Printable {
override fun draw() {
println("Document Drawing")
}
override fun print() {
println("Document Printing")
}
}
fun main() {
val drawable1: Drawable1 = Document()
// 강제 타입 변환 사용
val doc = drawable1 as Document
doc.draw() // 출력: Document Drawing
doc.print() // 출력: Document Printing
}
- drawable은 Drawable 타입으로 선언되었지만, 실제 객체는 Document 타입이다.
- `as` 키워드를 사용하여 drawable을 Document로 강제 변환한다.
- 변환이 성공하면 draw()와 print() 메서드를 호출할 수 있다.
제네릭 클래스
fun main() {
val box1 = Box(10) // Box<Int> 타입의 인스턴스 생성
val box2 = Box("apple") // Box<String> 타입의 인스턴스 생성
println(box1.value) // 출력: 10
println(box2.value) // 출력: apple
}
class Box<T>(var value: T) {
// 제네릭 클래스 정의
}
`Box<T>`
- Box 클래스는 `제네릭`으로 정의되어 있어서 다양한 타입을 담을 수 있다.
- <T>는 타입 파라미터로, 클래스가 생성될 때 실제 타입이 결정된다. 이 경우 T가 Int 또는 String으로 대체되었다.
콜백 함수 (고차함수)
fun main() {
myFunc {
println("함수 호출")
}
}
fun myFunc(callBack : () -> Unit) {
println("함수 Start")
callBack()
println("함수 End")
}
/*
함수 Start
함수 호출
함수 End
*/
`고차 함수 myFunc`
- myFunc는 매개변수로 람다식을 받는 함수이다.
- callBack: () -> `Unit`은 반환 값이 없는 함수 타입을 나타내고 있다. Unit은 자바의 void와 비슷한 역할이다..
- 이 함수는 println("함수 Start")를 출력한 후, callBack을 호출하고 마지막으로 println("함수 End")를 출력한다.
마치며
코틀린 핵심 문법을 정리해보았다.
자바를 사용했었기에 크게 어렵지 않았다. 코틀린으로 백엔드 프로젝트를 일주일만 해보면 익숙해질 것으로 생각된다.
다음 시간에는 인프런 강의와 함께 `코틀린 + 스프링 Api 호출하기`를 해보려고 한다.
반응형
'프로그래밍 언어' 카테고리의 다른 글
코틀린(Kotlin)의 핵심 문법과 예제 (1/2) (0) | 2025.01.06 |
---|