Kotlin/이해하기

[Kotlin] Kotlin 기본 문법 이해하기 -3 : 클래스, 인터페이스, 구현체

adjh54 2024. 11. 23. 15:35
반응형
해당 글에서는 Kotlin의 기본 문법 중 클래스, 인터페이스, 구현체에 대해 알아봅니다

 

💡 [참고] Kotlin의 문법들에 대해 궁금하시면 아래의 글을 참고하시면 도움이 됩니다.
주제 링크
Kotlin 기본 문법 이해하기 -1 : 주요 특징 및 문법 이해(변수 및 데이터 타입, 캐스팅, Null) https://adjh54.tistory.com/607
Kotlin 기본 문법 이해하기 -2 : Control flow (조건식, RANGE, 반복문) https://adjh54.tistory.com/608
Kotlin 기본 문법 이해하기 -3 : 클래스, 인터페이스, 구현체 https://adjh54.tistory.com/609
Kotlin 기본 문법 이해하기 -4 : 함수, 파라미터, 스코프 함수 https://adjh54.tistory.com/610

 

1) Kotlin 클래스(Class) 구성


💡 Kotlin 클래스(Class) 구성

- 클래스는 객체 지향 프로그래밍의 기본 구성요소입니다. 이는 데이터와 그 데이터를 조작하는 코드를 하나의 단위로 묶는 틀입니다.

 

 

1. 클래스(Class)


💡 클래스(Class)

- Kotlin에서 클래스는 'class' 키워드를 사용하여 선언합니다.
- 클래스 이름, 클래스 헤더(유형 매개변수, 기본 생성자 및 기타 몇 가지 지정) 및 중괄호로 둘러싼 클래스 본문으로 구성됩니다.
- 클래스에 본문이 없으면 중괄호를 생략할 수 있습니다.
 

Classes | Kotlin

 

kotlinlang.org

 

💡 클래스 사용예시

1. 클래스 선언방법-1 : 클래스 헤더가 존재하지 않는 형태
- 클래스 헤더는 매개변수나 기본 생성자를 의미합니다. 이를 사용하지 않은 클래스를 선언하는 예시입니다.

2. 클래스 선언 방법-2: 클래스 헤더(매개변수)가 존재하는 경우
- 클래스 헤더로 매개변수를 받는 경우를 의미합니다. 즉, 인스턴스화 할때, 필수로 매개변수로 id, name 값을 받는 클래스를 선언하는 예시입니다.

3. 클래스 선언 방법-3: 본문이 없는 경우

- 클래스로 선언하였지만, 본문에 내용이 없는 경우를 의미합니다. 이는 향후 확장을 위한 자리 표시자로 사용될 수 있습니다.
// 클래스 선언 방법-1: 클래스 헤더가 존재하지 않는 형태
class Person {
    // 클래스 본문
    var name: String = ""
    var age: Int = 0
}

// 클래스 선언 방법-2: 클래스 헤더(매개변수)가 존재하는 경우
class Student(private val id: Int, private var name: String) {
    // 클래스 본문
    fun introduce() {
        println("My name is $name and my student ID is $id")
    }
}

// 클래스 선언 방법-3: 본문이 없는 경우
class EmptyClass;

 

 

2. 생성자(Constructor)


💡 생성자(Constructor)

- Kotlin 클래스는 주 생성자와 하나 이상의 보조 생성자를 가질 수 있습니다.
- 기본 생성자는 클래스 헤더에 선언되며 클래스 이름과 매개변수 뒤에 옵니다.
생성자 종류 설명
주 생성자 (Primary Constructor) 클래스가 인스턴스화될 때 반드시 필요한 핵심 매개변수를 정의합니다.
보조 생성자 (Secondary Constructor) 다양한 매개변수 조합으로 객체를 생성할 수 있게 합니다.

 

 

Classes | Kotlin

 

kotlinlang.org

 

💡 [참고] 주 생성자와 보조 생성자 비교
구분 주 생성자 보조 생성자
정의 위치 클래스 헤더에 정의 클래스 본문에 정의
키워드 constructor (생략 가능) constructor (필수)
개수 하나만 가능 여러 개 가능
초기화 블록 init 블록 사용 자체 본문 내에서 초기화
다른 생성자 호출 해당 없음 this 키워드로 주 생성자 또는 다른 보조 생성자 호출 필요
프로퍼티 선언 매개변수에 var/val 사용 가능 매개변수에 var/val 사용 불가

 

 

💡 생성자 선언 방법

1. 생성자 선언 방법-1: 클래스 이름과 매개변수 뒤에 constructor 선언하는 경우

- 클래스 구성 시 ‘constructor’를 통해서 생성자도 함께 생성하는 경우를 의미합니다.

2. 생성자 선언 방법-2: constructor를 사용하지 않는 경우

- 해당 경우에서는 매개변수들은 자동으로 클래스의 주 생성자가 됩니다.이 방식으로 선언된 매개변수들은 클래스 내부에서 사용할 수 있지만, 자동으로 프로퍼티가 되지는 않습니다.

3. 생성자 선언 방법-3 : 주 생성자와 보조 생성자가 존재하는 경우

- 해당 경우에서는 name, age라는 값을 이용하여 주 생성자를 구성하였습니다.
- 클래스 본문 내에서 constructor를 통해서 name의 값은 필수 매개변수로 받으면서, age라는 매개변수에 대해서는 0으로 초기화를 하여 선택적으로 인스턴스화 할 수 있도록 구성합니다.
package com.blog.kotlinspringbootform.component

// 생성자 선언 방법-1: 클래스 이름과 매개변수 뒤에 constructor 선언하는 경우
class ConstructorComponent constructor(firstName: String) {
    init {
        // 생성자 초기화 수행
    }
}

// 생성자 선언 방법-2: constructor를 사용하지 않는 경우
class ConstructorComponent(firstName: String, lastName: String, age: Int) {
    init {
        // 생성자 초기화 수행
    }
}

// 생성자 선언 방법-3 : 주 생성자와 보조 생성자가 존재하는 경우
class Person(val name: String, var age: Int) {
    // 주 생성자
    
    init {
        // 생성자 초기화 수행
    }
    
    constructor(name: String) : this(name, 0) {
        // 보조 생성자
    }

}

// 아래와 같은 구조를 통해 객체 생성 시 유연성을 제공합니다.
val person1 = Person("Alice", 30)  // 주 생성자 사용
val person2 = Person("Bob")        // 보조 생성자 사용, age는 0으로 초기화됨

 

 

3. 클래스 인스턴스 생성(Creating instances of classes)


💡 클래스 인스턴스 생성(Creating instances of classes)

- Kotlin에서 클래스의 인스턴스를 생성할 때는 new 키워드를 사용하지 않습니다.
- 클래스 이름 뒤에 괄호를 붙여 생성자를 호출합니다.
- 생성자에 매개변수가 있는 경우, 해당 매개변수를 괄호 안에 전달합니다.

 

// 매개변수가 없는 생성자
val invoice = Invoice()

// 매개변수가 있는 생성자
val customer = Customer("Joe Smith")

// 여러 매개변수를 가진 생성자
val person = Person("Alice", 30)

// 명명된 매개변수를 사용한 생성자 호출
val employee = Employee(name = "Bob", age = 35, department = "IT")

 

 

4. init block


💡 init block

- 클래스의 초기화 코드를 포함하는 특별한 블록을 의미합니다.
- 주 생성자의 일부로 실행되며, 클래스가 인스턴스화될 때 호출됩니다.
- 클래스 내에 여러 init 블록을 가질 수 있으며, 이들은 클래스 본문에 나타나는 순서대로 실행됩니다.
특징 설명
초기화 순서 클래스 본문에 나타나는 순서대로 실행됩니다.
주 생성자와의 관계 주 생성자의 일부로 실행되며, 주 생성자 매개변수에 접근할 수 있습니다.
다중 사용 하나의 클래스에 여러 init 블록을 정의할 수 있습니다.
프로퍼티 초기화 프로퍼티 초기화와 교차적으로 실행됩니다.
예외 처리 초기화 중 예외를 던질 수 있어 객체 생성 실패를 명시적으로 처리할 수 있습니다.
class Person(val name: String) {
    var age: Int = 0

    init {
        println("Person instance created with name: $name")
    }

    init {
        println("This is the second init block")
    }
}

// 사용 예
val person = Person("Alice")
// 출력:
// Person instance created with name: Alice
// This is the second init block

 

 

5. 프로퍼티(Properties)


💡 프로퍼티(Properties)

- 클래스는 프로퍼티를 가질 수 있으며, 이는 주 생성자에서 선언하거나 클래스 본문에서 선언할 수 있습니다.
- 해당 프로퍼티는 Java의 멤버 변수와 다르게 getter, setter를 자동으로 생성합니다.
- val로 생성한 프로퍼티는 읽기전용으로 gettter가 되지만, var로 생성한 프로퍼티는 getter/setter로 읽기 쓰기가 가능합니다.

 

💡 프로퍼티 예시

- Person 클래스 내에 email 이라는 프로퍼티를 클래스 내에 선언하였습니다.
class Person(val name: String, var age: Int) {
    var email: String = ""
}

 

 

Properties | Kotlin

 

kotlinlang.org

 

[ 더 알아보기 ]

💡 프로퍼티가 Java에서 멤버변수와 같은것을 의미하는 걸까?

- 프로퍼티는 Kotlin의 개념으로, getter와 setter를 자동으로 생성합니다.
- 멤버 변수는 Java의 개념으로, 단순히 클래스 내부의 변수를 의미합니다.
- 따라서, Kotlin의 프로퍼티는 멤버 변수의 개념을 포함하면서도 더 확장된 기능을 제공한다고 볼 수 있습니다.

 

5. 함수(Functions)


💡 함수(Functions)

- 클래스 내에 함수를 정의하여 메서드를 만들 수 있습니다
class Person(val name: String, var age: Int) {
		// 메서드 선언부
    fun introduce() {
        println("My name is $name and I'm $age years old.")
    }
}

// Person 클래스의 인스턴스 생성
val person = Person("Alice", 30)

// introduce 메서드 호출 : My name is Alice and I'm 30 years old. 출력
person.introduce()
 

Functions | Kotlin

 

kotlinlang.org

 

6. 상속(Extensions)


💡 상속(Extensions)

- Kotlin에서 클래스는 기본적으로 final이며, 상속을 허용하려면 'open' 키워드를 사용해야 합니다.
 

Extensions | Kotlin

 

kotlinlang.org

 

💡 사용예시

- Animal 클래스 내에서 ‘open’ 키워드를 두어서 외부에서 상속하는것에 대해서 허용합니다. 즉, Dog 클래스 기준으로 Animal 클래스로 부터 상속을 받습니다.
- 이를 상속받은 Dog 클래스 내에서는 Anmal 클래스의 makeSound() 메서드를 오버라이딩 합니다
open class Animal(val name: String) {
    open fun makeSound() {
        println("The animal makes a sound")
    }
}

class Dog(name: String) : Animal(name) {
    override fun makeSound() {
        println("The dog barks")
    }
}

 

 

 

반응형

 

 

2) Kotlin 클래스(Class) 종류


 

1. 추상 클래스(Abstract Class)


💡 추상 클래스(Abstract Class)

- 'abstract' 키워드를 사용하여 선언합니다. 이는 직접 인스턴스화 할 수 없으며 다른 클래스가 상속받아 구현해야 합니다.
- 추상 클래스는 추상 메서드(구현이 없는 메서드)를 포함할 수 있고 일반 메서드와 프로퍼티도 포함할 수 있습니다.
특징 설명
부분적인 구현 일부 메서드는 구현하고, 일부는 추상으로 남겨둘 수 있습니다.
상속 다른 클래스가 추상 클래스를 상속받아 추상 메서드를 구현해야 합니다.
다형성 추상 클래스 타입의 변수로 하위 클래스의 인스턴스를 참조할 수 있습니다.
공통 기능 정의 여러 하위 클래스에서 공유할 수 있는 공통 기능을 정의할 수 있습니다.
abstract class Shape {
    abstract fun draw() // 추상 메서드
    
    fun moveTo(x: Int, y: Int) { // 일반 메서드
        println("Moving to ($x, $y)")
    }
}

class Circle : Shape() {
    override fun draw() {
        println("Drawing a circle")
    }
}

// 사용 예
val circle = Circle()
circle.draw()    // 출력: Drawing a circle
circle.moveTo(10, 20) // 출력: Moving to (10, 20)
 

Classes | Kotlin

 

kotlinlang.org

 

2. 데이터 클래스(Data Class)


💡 데이터 클래스(Data Class)

- Kotlin은 데이터를 보유하는 목적의 클래스를 위한 특별한 'data class'를 제공합니다.
- 일반적으로 구성하는 VO, DTO에 대한 정의를 위함입니다.

 

 

특징 설명
자동 생성 메서드 컴파일러가 자동으로 equals(), hashCode(), toString(), copy() 메서드를 생성. 코드 작성 시간 절약 및 오류 가능성 감소.
불변성 지원 주 생성자에서 프로퍼티를 val로 선언하여 불변 객체를 쉽게 생성 가능.
구조 분해 데이터 클래스 객체를 쉽게 구조 분해하여 여러 변수에 객체의 프로퍼티 할당 가능.
간결한 문법 최소한의 코드로 데이터 모델을 정의하여 코드의 가독성 향상.

 

💡 data class 사용예시

- 아래와 같이 data 클래스로 구성을 하는 경우, 별도의 getter/setter/toString 구성 없이도 접근이 가능합니다.
package com.blog.kotlinspringbootform.dto

data class UserDto(
    val userSq: Int,    // 사용자 시퀀스
    val userId: String, // 사용자 아이디
    val userPw: String, // 사용자 패스워드
    val userNm: String, // 사용자 이름
    val userSt: String, // 사용자 상태
)

 

 

💡 data class 호출 예시

- 타입을 UserDto로 지정한 user를 생성하여 data 클래스를 호출합니다.
- UserDto의 파라미터를 통해서 각각의 값에 대해서 setter를 구성합니다.
- userDto 객체의 프로퍼티에 접근하여 호출을 합니다.
- userDto.toString() 메서드를 통해서 객체를 직렬화하여 호출합니다.
/**
 * 데이터 클래스를 호출합니다.
 */
fun dataClassCall() {

    val user: DataClassComponent

    // setter
    val userDto: DataClassComponent = DataClassComponent(userSq = 1, userNm = "lee", userId = "adjh54", userSt = "S", userPw = "password")

    // getter
    userDto.also {
        println("userSq : ${it.userSq}")
        println("userNm : ${it.userNm}")
        println("userId : ${it.userId}")
        println("userPw : ${it.userPw}")
    }

    // toString
    println("userDto : ${userDto.toString()}")
}

 

[더 알아보기]

💡 Kotlin에서는 Builder 패턴을 사용하지 않는가?

- Kotlin에서는 일반적으로 Builder 패턴을 직접적으로 사용하지 않습니다.
- Kotlin의 언어 기능들이 Builder 패턴의 장점을 대체할 수 있기 때문입니다.
- 그러나 복잡한 객체 생성 로직이 필요한 경우는 Builder 패턴을 이용하여 구현합니다.

 

💡 [참고] 아래와 같은 형태로 Builder 패턴을 대체하여 사용합니다.
data class Person(
    val name: String,
    val age: Int = 0,
    val email: String? = null
)

// 사용 예
val person = Person(
    name = "John",
    age = 30,
    email = "john@example.com"
)

 

 

3. Enum 클래스(Enum Class)


💡 Enum 클래스(Enum Class)

- Kotlin에서 Enum 클래스는 'enum class' 키워드를 사용하여 선언합니다.
- Enum 클래스는 미리 정의된 상수들의 집합을 나타내는 특별한 종류의 클래스입니다.
 

Enum classes | Kotlin

 

kotlinlang.org

 

특징 설명
상수 정의 고정된 값들의 집합을 표현할 때 사용합니다.
프로퍼티와 메서드 Enum 상수에 프로퍼티를 추가하거나 메서드를 정의할 수 있습니다.
when 표현식과 함께 사용 Enum 클래스는 when 표현식과 함께 사용하여 모든 경우를 처리할 수 있습니다.

 

 

💡 Enum 클래스 예시

- 아래와 같이 EnumDirection, EnumDayOfWeek 두 개의 enum class가 있습니다.

1. EnumDirection의 경우는 각각 값에 대해서 관리를 합니다.
2. EnumDayOfWeek의 경우는 코드 형태로 SUNDAY 값을 호출하는 경우 숫자로 반환합니다.
/**
 * 상수로 값을 지정한 ENUM CLASS
 */
enum class EnumDirection {
    NORTH, SOUTH, EAST, WEST
}

/**
 * 일자를 숫자로 가지고 있습니다.
 */
enum class EnumDayOfWeek(val value: Int) {
    SUNDAY(1),
    MONDAY(2),
    TUESDAY(3),
    WEDNESDAY(4),
    THURSDAY(5),
    FRIDAY(6),
    SATURDAY(7);

    fun isWeekend(): Boolean {
        return this == SATURDAY || this == SUNDAY
    }
}

 fun enumClassCall() {
    // EnumDirection 사용 예시
    val direction = EnumDirection.NORTH
    println("Selected direction: $direction")                   // Selected direction: NORTH

    // EnumDayOfWeek 사용 예시
    val today = EnumDayOfWeek.WEDNESDAY
    println("Today is: $today")                                 // Today is: WEDNESDAY
    println("Today's value: ${today.value}")                    // Today's value: 4
    println("Is today a weekend? ${today.isWeekend()}")         // Is today a weekend? false

    val saturday = EnumDayOfWeek.SATURDAY
    println("Is Saturday a weekend? ${saturday.isWeekend()}")   // Is Saturday a weekend? true
}

 

 

4. 중첩 클래스(Nested Class)


💡 중첩 클래스(Nested Class)

- Kotlin에서 중첩 클래스는 다른 클래스 내부에 선언된 클래스입니다.
- 기본적으로 정적(static)이며, 외부 클래스의 인스턴스에 대한 참조를 갖지 않습니다.
- 외부 클래스의 private 멤버를 포함한 모든 멤버에 접근할 수 없습니다.
특징 설명
정적 특성 외부 클래스의 인스턴스 없이 생성 및 사용 가능
독립성 외부 클래스의 멤버에 직접 접근 불가
캡슐화 관련 클래스를 그룹화하여 코드 구조화에 도움
메모리 효율 외부 클래스의 인스턴스를 참조하지 않아 메모리 효율적

 

 

Nested and inner classes | Kotlin

 

kotlinlang.org

 

💡 중첩 클래스 사용 예시

- 아래 예시에서 NestedClass는 OuterClass 내부에 선언되었지만, OuterClass의 멤버에 직접 접근할 수 없습니다.
class OuterClass {
    private val outerProperty = "Outer Property"

    class NestedClass {
        fun nestedMethod() {
            println("This is a nested class method")
            // 오류: outerProperty에 직접 접근 불가
            // println(outerProperty)
        }
    }

    fun outerMethod() {
        val nested = NestedClass()
        nested.nestedMethod()
    }
}

fun main() {
    val nestedInstance = OuterClass.NestedClass()
    nestedInstance.nestedMethod()

    val outerInstance = OuterClass()
    outerInstance.outerMethod()
}

 

 

5. 내부 클래스(Inner Class)


💡 내부 클래스(Inner Class)

- Kotlin에서 inner class는 외부 클래스의 멤버에 접근할 수 있는 중첩 클래스입니다.
- 'inner' 키워드를 사용하여 선언합니다.
- 외부 클래스의 인스턴스에 대한 참조를 가집니다.
Inner Class의 특징 설명
외부 클래스의 멤버에 접근 가능 Inner class는 외부 클래스의 private 멤버를 포함한 모든 멤버에 접근할 수 있습니다.
외부 클래스의 인스턴스와 연결됨 Inner class의 인스턴스는 항상 외부 클래스의 인스턴스와 연관되어 있습니다.
메모리 누수에 주의해야 함 외부 클래스의 인스턴스에 대한 참조를 유지하므로, 부주의하게 사용하면 메모리 누수의 원인이 될 수 있습니다.

 

 

Nested and inner classes | Kotlin

 

kotlinlang.org

 

💡 사용예시

- ClassComponent 라는 클래스 내에서 내부 클래스로 InnerClass를 생성했습니다. 이 생성된 클래스는 함수내에서 호출이 가능합니다.
- outer라는 변수에 인스턴스를 생성하고, inner라는 변수에 내부 클래스를 호출하도록 구성하였습니다.
- 최종적으로 내부 클래스의 메서드에 접근하여서 호출을 하여 “Hello from Outer” 라는 콘솔에 출력을 하였습니다.
@Component
class ClassComponent() {

    private val message: String = "Hello from Outer"

    inner class InnerClass {
        fun greet() = println(message)
    }

  /**
     * 내부 클래스 호출 사용예시
     */
    fun innerClassCall() {
        val outer = ClassComponent()
        val inner = outer.InnerClass()
        inner.greet()  // 출력: Hello from Outer
    }
}

 

3) Kotlin 인터페이스


 

1. Kotlin 인터페이스


💡 Kotlin 인터페이스

- Kotlin에서 인터페이스는 ‘interface’ 키워드를 사용하여 선언합니다.
- 인터페이스의 경우는 추상 메서드와 디폴트 메서드를 포함할 수 있습니다.
 

Interfaces | Kotlin

 

kotlinlang.org

 

1.1. 일반 인터페이스 구현


💡 일반 인터페이스 구현

- interface 파일명 형태로 인터페이스를 구현합니다.

 

💡 기본 구조

- 아래와 같이 서비스 컴포넌트임을 나태는 @Service 어노테이션을 선언하고 interface [파일명] 형태로 인터페이스를 선언합니다.
@Service
interface [파일명]

 

 

💡 사용예시

- 아래와 같이 서비스 컴포넌트 임을 나태는 @Service 어노테이션을 선언하고 interface UserService 형태로 인터페이스를 구성하였습니다.
- 인터페이스 내에서는 추상 메서드 형태 혹은 디폴트 메시지 형태로 구성을 하였습니다
메서드 종류 특징 예시
추상 메서드 구현부가 없는 메서드로, 구현체에서 반드시 오버라이드해야 함 fun selectUserList(userDto: UserDto): List<UserDto>
디폴트 메서드 인터페이스에서 기본 구현을 제공하는 메서드로, 구현체에서 선택적으로 오버라이드 가능 fun showDefaultMethod(userDto: UserDto) { println("default Method...") }
package com.blog.kotlinspringbootform.service

import com.blog.kotlinspringbootform.dto.UserDto
import org.springframework.stereotype.Service

@Service
interface UserService {

    // 추상 메서드
    fun selectUserList(userDto: UserDto): List<UserDto>

    // 추상 메서드
    fun insertUser(userDto: UserDto): Int

    // 추상 메서드
    fun updateUser(userDto: UserDto): Int

    // 추상 메서드
    fun deleteUserList(userDto: List<UserDto>)

    // 디폴트 메서드
    fun showDefaultMethod(userDto: UserDto) {
        println("default Method...")
    }
}

 

 

1.2. 인터페이스의 구현체 구현


💡 인터페이스의 구현체 구현

- 위에 구성한 인터페이스의 실제 비즈니스 로직을 처리하는 부분입니다.
- 아래와 같이 : 인터페이스 구조로 이를 구현합니다.

 

 

💡 기본 구조

- 아래와 같이 서비스 컴포넌트임을 나태는 @Service 어노테이션을 선언하고 class [파일명] : [인터페이스 명] 형태로 구성을 합니다.
- overrid fun 함수명 형태로 추상 메서드를 실제 구현합니다.
@Service
class [파일명] : [인터페이스명] {

    // 추상 메서드 구현
    override fun [메서드명](userDto: UserDto): List<UserDto> {
        TODO("Not yet implemented")
    }
}

 

💡 사용예시

- 아래와 같이 서비스 컴포넌트임을 나태는 @Service 어노테이션을 선언하고 class [파일명] : [인터페이스 명] 형태로 구성을 합니다.
- 메서드는 인터페이스에서 추상 메서드로 구현한 내용에 대해 실제 비즈니스 로직을 처리합니다.
package com.blog.kotlinspringbootform.service.impl

import com.blog.kotlinspringbootform.model.dto.UserDto
import com.blog.kotlinspringbootform.service.UserService
import org.springframework.stereotype.Service

@Service
class UserServiceImpl : UserService {
    override fun selectUserList(userDto: UserDto): List<UserDto> {
        TODO("Not yet implemented")
    }

    override fun insertUser(userDto: UserDto): Int {
        TODO("Not yet implemented")
    }

    override fun updateUser(userDto: UserDto): Int {
        TODO("Not yet implemented")
    }

    override fun deleteUserList(userDto: List<UserDto>) {
        TODO("Not yet implemented")
    }

    override fun selectBoardList(any: Any): Any {
        TODO("Not yet implemented")
    }
}

 

 

1.3. 다중인터페이스 구현


💡 다중인터페이스 구현

- 추가적으로 BoardService를 구성하였습니다.
- 이전 UserService 인터페이스와 함께 다중인터페이스로 구현체를 구현하는 방법입니다.
package com.blog.kotlinspringbootform.service

import org.springframework.stereotype.Service

@Service
interface BoardService {
    fun selectBoardList(any: Any): Any
    fun insertBoard(any: Any): Int
    fun updateBoard(any: Any): Int
    fun deleteBoard(any: Any): Int
}

 

 💡 다중인터페이스 구현

- 구현체에서는 : UserService, BoardService를 통해서 두개의 인터페이스로 부터 구현체를 구성합니다.
package com.blog.kotlinspringbootform.service.impl

import com.blog.kotlinspringbootform.dto.UserDto
import com.blog.kotlinspringbootform.service.BoardService
import com.blog.kotlinspringbootform.service.UserService

class UserServiceImpl : UserService, BoardService {
    override fun selectUserList(userDto: UserDto): List<UserDto> {
        TODO("Not yet implemented")
    }

    override fun insertUser(userDto: UserDto): Int {
        TODO("Not yet implemented")
    }

    override fun updateUser(userDto: UserDto): Int {
        TODO("Not yet implemented")
    }

    override fun deleteUserList(userDto: List<UserDto>) {
        TODO("Not yet implemented")
    }

    override fun selectBoardList(any: Any): Any {
        TODO("Not yet implemented")
    }

    override fun insertBoard(any: Any): Int {
        TODO("Not yet implemented")
    }

    override fun updateBoard(any: Any): Int {
        TODO("Not yet implemented")
    }

    override fun deleteBoard(any: Any): Int {
        TODO("Not yet implemented")
    }
}

 

 

4) Kotlin 인터페이스의 구현체


💡 Kotlin 인터페이스 구현체

- 구현체는 'class' 키워드와 함께 콜론(:)을 사용하여 인터페이스를 구현합니다.
package com.blog.kotlinspringbootform.service.impl

import com.blog.kotlinspringbootform.dto.UserDto
import com.blog.kotlinspringbootform.service.UserService

class UserServiceImpl : UserService {
    override fun selectUserList(userDto: UserDto): List<UserDto> {
        TODO("Not yet implemented")
    }

    override fun insertUser(userDto: UserDto): Int {
        TODO("Not yet implemented")
    }

    override fun updateUser(userDto: UserDto): Int {
        TODO("Not yet implemented")
    }

    override fun deleteUserList(userDto: List<UserDto>) {
        TODO("Not yet implemented")
    }
}

 

 

Interfaces | Kotlin

 

kotlinlang.org

 

 

 

 

5) Kotlin 해당 글 주요 개념 요약


구분 설명
클래스(Class) - 'class' 키워드로 선언
- 데이터와 코드를 하나의 단위로 묶는 틀
- 클래스 이름, 헤더, 본문으로 구성
인터페이스(Interface) - 'interface' 키워드로 선언
- 추상 메서드와 디폴트 메서드 포함 가능
- @Service 어노테이션과 함께 사용
추상 메서드 - 구현부가 없는 메서드
- 구현체에서 반드시 오버라이드 필요
- 예: selectUserList(), insertUser() 등
디폴트 메서드 - 인터페이스에서 기본 구현을 제공
- 구현체에서 선택적으로 오버라이드 가능
구현체(Implementation) - 클래스에서 콜론(:)을 사용하여 인터페이스 구현
- override 키워드로 메서드 구현
- 다중 인터페이스 구현 가능

 

// 클래스 선언
class User {
    var name: String = ""
    var age: Int = 0
}

// 인터페이스 선언
interface UserService {
    // 추상 메서드
    fun getUser(id: Long): User
    
    // 디폴트 메서드
    fun printUserInfo(user: User) {
        println("User: ${user.name}, Age: ${user.age}")
    }
}

// 단일 인터페이스 구현
class UserServiceImpl : UserService {
    override fun getUser(id: Long): User {
        // 구현 로직
        return User()
    }
}

// 다중 인터페이스 구현
interface LogService {
    fun logInfo(message: String)
}

class UserServiceWithLogging : UserService, LogService {
    override fun getUser(id: Long): User {
        return User()
    }
    
    override fun logInfo(message: String) {
        println("Log: $message")
    }
}

 

 

 

오늘도 감사합니다. 😀

 

 

 

반응형