Kotlin에서 스코프(scope)는 변수, 함수, 객체 등이 접근 가능한 영역을 정의하는 개념입니다. 코틀린의 스코프는 블록(block), 클래스, 패키지, 그리고 파일 단위로 나뉘며, 이 스코프는 프로그램의 구조와 가독성, 유지보수성을 크게 향상시킵니다.


1. 스코프의 종류

(1) 지역 스코프 (Local Scope)

  • 변수나 함수가 특정 블록 {} 내에서만 접근 가능.
  • 일반적으로 if, for, while, 또는 함수 내에서 사용.

(2) 클래스 스코프 (Class Scope)

  • 클래스 내부에서 정의된 변수와 메서드는 해당 클래스의 스코프 안에서 접근 가능.
  • 클래스 내의 변수는 기본적으로 인스턴스 변수(멤버 변수)로 관리.

(3) 파일 스코프 (File Scope)

  • 파일에 정의된 함수나 변수는 파일 내부에서만 접근 가능.
  • 다른 파일에서 접근하려면 public, internal, private 접근자를 사용.

(4) 패키지 스코프 (Package Scope)

  • 패키지 내에 정의된 함수, 클래스, 객체 등이 패키지 내부에서 접근 가능.
  • 코틀린은 기본적으로 패키지 스코프를 제공하며, Java처럼 명시적으로 package를 선언하지 않아도 됨.

 

2. 스코프별 예시

(1) 지역 스코프

fun localScopeExample() {
    val outerVariable = "I'm accessible throughout this function"

    if (true) {
        val innerVariable = "I'm only accessible inside this if block"
        println(innerVariable) // 접근 가능
    }

    // println(innerVariable) // 오류: innerVariable은 if 블록 외부에서 접근 불가
    println(outerVariable) // 접근 가능
}

 

(2) 클래스 스코프

class Person(val name: String) {
    private val age: Int = 30 // 클래스 내부에서만 접근 가능

    fun displayInfo() {
        println("Name: $name, Age: $age") // 접근 가능
    }
}

fun classScopeExample() {
    val person = Person("John")
    person.displayInfo() // 가능
    // println(person.age) // 오류: age는 private 스코프
}

 

(3) 파일 스코프

private val fileVariable = "I'm only accessible in this file"

fun publicFunction() {
    println("I'm accessible from other files if imported")
}

private fun privateFunction() {
    println("I'm only accessible in this file")
}

 

다른 파일에서

import com.example.Utils.publicFunction

fun fileScopeExample() {
    publicFunction() // 가능
    // privateFunction() // 오류: privateFunction은 접근 불가
    // println(fileVariable) // 오류: fileVariable은 접근 불가
}

 

(4) 패키지 스코프

package com.example

fun packageScopedFunction() {
    println("I'm accessible within this package")
}

다른 패키지에서:

import com.example.packageScopedFunction

fun main() {
    packageScopedFunction() // 가능 (default: public)
}

3. Kotlin 스코프 함수

코틀린에는 **스코프 함수(scope functions)**라고 하는 특수한 함수도 있습니다. 이 함수들은 람다 블록 내에서 객체를 다룰 수 있는 간결한 방법을 제공합니다.

스코프 함수 종류

  • let
  • run
  • with
  • apply
  • also

 

kotlin 스코프 함수에 대해서는 다음번 글에 상세히 알아아보도롭 하겠습니다.

안드로이드를 개발하다 보면 기본 화면 및 UI에 대한 설정이 필요한 경우가 있습니다.

하지만 onCreate 와 onPostCreate로 구분지어 작업해야하는 경우가 있습니다. 아래 내용은 해당 함수의 차이점을 알아보고 사용 예를 알아보아요.

 

onCreate와 onPostCreate의 주요 차이는 호출 시점UI 초기화 완료 여부입니다. 이 두 메서드는 모두 Activity의 생명 주기에서 호출되지만, 각 메서드의 호출 시점과 목적이 다릅니다.

 

1. onCreate

  • 호출 시점: Activity가 생성되는 가장 초기 단계에서 호출됩니다.
  • 목적: Activity의 기본 초기화 작업을 수행합니다.
  • 주요 작업:
    • setContentView로 레이아웃을 설정합니다.
    • ViewModel, DataBinding, Intent 데이터 초기화 등 초기 설정을 수행합니다.

onCreate에서는 UI 요소가 아직 완전히 레이아웃되지 않았기 때문에 크기나 위치 같은 동적 레이아웃 정보를 정확하게 얻을 수 없습니다.

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)  // 레이아웃 설정
    // 초기화 작업 수행
}

 

2. onPostCreate

  • 호출 시점: onCreate가 끝난 직후, Activity가 초기화된 후 호출됩니다.
  • 목적: Activity가 완전히 생성된 후 추가 UI 설정이나 동적 레이아웃 작업을 수행합니다.
  • 주요 작업:
    • onCreate 이후 추가적인 UI 작업을 수행하기 적합한 메서드입니다.
    • 상태 표시줄이나 window 관련 설정을 하는 데 유용합니다.

onPostCreate는 Activity의 초기화가 끝난 후 호출되므로, UI가 그려지기 전에 수행해야 하는 추가 설정이나 window 설정 등을 안전하게 처리할 수 있습니다.

override fun onPostCreate(savedInstanceState: Bundle?) {
    super.onPostCreate(savedInstanceState)
    // 추가 UI 설정, 예를 들어 상태 표시줄 색상 설정
}

 

onCreate와 onPostCreate의 차이 요약

매서드 호출시점 주요목적 작업 예시
onCreate Activity 초기 생성 단계 기본 초기화 및 레이아웃 설정 setContentView, Intent 처리
onPostCreate onCreate가 완료된 직후 추가 UI 설정 및 window 설정 상태 표시줄, 전체 화면 설정

 

언제 onPostCreate를 사용하는 것이 좋은가요?

  • 상태 표시줄, window 속성 설정 등 UI가 완전히 초기화되기 전에 설정해야 하는 추가적인 UI 작업이 있는 경우.
  • onCreate에서만 처리할 수 없는 추가적인 레이아웃 초기화나 window 설정이 필요한 경우.

따라서 onCreate는 기본 초기화 및 레이아웃 설정에 주로 사용되고, onPostCreate는 추가 UI 설정 작업에 더 적합한 메서드입니다.

코틀린 suspend에 대한 내용을 아래와 같이 정리해보았습니다. 

개념 및 사용예제를 통해 이해해보자.

 

suspend란?

Kotlin에서 suspend 키워드는 코루틴을 사용해 비동기 작업을 처리하기 위해 함수에 붙이는 키워드입니다. suspend 함수는 일반 함수처럼 호출할 수 없으며, 코루틴 내부 또는 다른 suspend 함수에서만 호출할 수 있습니다. 이는 해당 함수가 잠재적으로 시간이 오래 걸릴 수 있는 작업을 포함하고 있다는 의미입니다. 예를 들어, 네트워크 요청이나 파일 I/O와 같은 작업은 코루틴을 사용해 메인 스레드를 차단하지 않고 처리할 수 있습니다.

 

suspend 함수의 특징

  1. 비동기 처리 지원: suspend 함수는 비동기로 실행될 수 있어 메인 스레드를 차단하지 않고도 장시간 작업을 수행할 수 있습니다.
  2. 컨텍스트 전환: suspend 키워드를 사용하면 코루틴이 특정 시점에서 중단되었다가 다시 재개될 수 있어 효율적인 스레드 관리가 가능합니다.
  3. 코드 가독성 향상: suspend 함수는 일반적인 비동기 콜백 코드보다 가독성이 높아지고 유지보수성이 증가합니다.

 

suspend 함수 예제

suspend fun fetchData(): String {
    delay(1000L) // 네트워크 요청을 시뮬레이션하는 지연 함수
    return "데이터가 성공적으로 로드되었습니다."
}

fun main() = runBlocking {
    println("로딩 중...")
    val result = fetchData() // `fetchData`가 완료될 때까지 기다립니다.
    println(result)
}

 

위 예제에서 fetchData는 suspend 함수이므로, runBlocking과 같은 코루틴 빌더 내부에서 호출해야 합니다. delay 함수는 일종의 비동기 함수로, Thread.sleep과 달리 스레드를 차단하지 않고 지연을 발생시킵니다.

 

언제 suspend를 사용할지 고려해야 하는 경우

  • 네트워크 요청: 서버에서 데이터를 가져오는 HTTP 요청
  • 데이터베이스 쿼리: 로컬 또는 원격 데이터베이스 접근
  • 파일 I/O 작업: 파일 읽기 및 쓰기 작업
  • 리스트나 대량 데이터 처리: 비동기적으로 처리할 때 유리합니다.

suspend 함수를 설계할 때 작업의 시간이 오래 걸릴 것으로 예상되거나 비동기 처리가 필요한 경우에만 적용하는 것이 좋습니다.

'Kotlin' 카테고리의 다른 글

[코틀린] 스코프란? - 개념 이해하기  (0) 2024.11.22
코틀린에서 함수 재정의(overriding)하기  (2) 2024.11.06

 

오늘 withContext라는 개념에 대해 알아보겠습니다.

 

withContext란?

Android의 withContext는 Kotlin 코루틴에서 코루틴 컨텍스트를 변경하면서 비동기 작업을 수행하는 데 사용됩니다. 간단히 말해서, 현재 코루틴을 특정 디스패처로 이동하여, 그 환경에서 특정 코드를 실행하도록 합니다. Android에서 일반적으로 UI 스레드와 백그라운드 스레드 간 전환을 쉽게 하도록 도와주는 중요한 도구입니다.

 

기본 개념

withContext는 비동기 코드 블록을 지정한 디스패처에서 실행하게 하며, 특정 코드가 완료될 때까지 일시 중단합니다. 코드가 완료되면 원래의 컨텍스트로 돌아가서 이후 작업을 이어서 수행할 수 있습니다.

 

주요 사용 사례

1. UI 스레드와 백그라운드 스레드 간 전환
Android에서는 네트워크 요청이나 데이터베이스 작업 같은 오래 걸리는 작업을 메인(UI) 스레드에서 수행하지 않도록 권장합니다. 이런 경우 Dispatchers.IO 또는 Dispatchers.Default와 함께 withContext를 사용하여 백그라운드 스레드에서 작업을 처리할 수 있습니다.

// 코루틴 내부에서 사용 예시
val result = withContext(Dispatchers.IO) {
    // 네트워크 호출이나 DB 작업 등
    myDatabase.queryData()
}
// 결과를 UI에 반영 (메인 스레드에서 수행됨)
textView.text = result

 

2. CPU 집약적인 작업
이미지 처리나 데이터 변환 등 CPU를 많이 사용하는 작업을 Dispatchers.Default로 옮겨 CPU 리소스를 최적화하면서 메인 스레드를 차단하지 않도록 할 수 있습니다.

val processedData = withContext(Dispatchers.Default) {
    processData(data) // CPU 집약적인 작업
}

 

3. UI 업데이트 작업
네트워크 작업이나 데이터 처리가 완료된 후 다시 UI 작업으로 돌아올 때 Dispatchers.Main을 사용해 메인 스레드에서 UI를 안전하게 업데이트할 수 있습니다.

withContext(Dispatchers.Main) {
    textView.text = "Data Loaded"
}

 

장점

  • 컨텍스트 전환이 간단: withContext를 사용하면 코드 블록 내에서 비동기 작업을 손쉽게 컨텍스트 변경을 통해 실행할 수 있습니다.
  • 코드 가독성: 콜백이나 복잡한 핸들러를 사용하지 않아도 되므로, 코드를 더욱 간결하고 이해하기 쉽게 만듭니다.
  • 효율적인 리소스 사용: 필요에 따라 적절한 디스패처로 전환하여 리소스를 효율적으로 사용할 수 있습니다.

 

Android에서 withContext는 비동기 작업을 적절한 스레드에서 수행할 수 있도록 도와주는 코루틴 기능입니다. 이를 통해 UI 스레드와 백그라운드 스레드 간의 전환을 쉽게 구현할 수 있으며, Dispatchers.Main, Dispatchers.IO, Dispatchers.Default 등의 디스패처를 지정하여 효율적이고 안전하게 비동기 작업을 수행할 수 있습니다.

 

@AndroidEntryPoint는 Hilt의 핵심 어노테이션으로, Android 컴포넌트(Activity, Fragment, Service 등)에 의존성 주입을 활성화하는 역할을 합니다. 이를 통해 Hilt는 해당 컴포넌트가 생성될 때 자동으로 필요한 의존성을 주입할 수 있게 됩니다.

 

사용 방법

Hilt를 사용하면 각 Android 컴포넌트에 @AndroidEntryPoint를 추가하고, Hilt가 제공하는 의존성을 주입받을 수 있습니다. 예를 들어, Activity나 Fragment에 @AndroidEntryPoint를 추가하고, ViewModel, Repository, ApiService 등과 같은 의존성을 주입받을 수 있습니다.

예시

1. Activity에서 사용

@AndroidEntryPoint
class GameActivity : AppCompatActivity() {

    // Hilt가 GameViewModel을 주입
    private val gameViewModel: GameViewModel by viewModels()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_game)

        // ViewModel을 사용하여 게임 데이터를 가져오는 로직
    }
}

2. Fragment에서 사용

@AndroidEntryPoint
class GameFragment : Fragment(R.layout.fragment_game) {

    // Hilt가 GameViewModel을 주입
    private val gameViewModel: GameViewModel by viewModels()

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        // ViewModel을 사용하여 데이터를 가져오는 등의 작업
    }
}

 

3. Service에서 사용

@AndroidEntryPoint
class GameService : Service() {

    // Hilt가 GameRepository를 주입
    @Inject lateinit var gameRepository: GameRepository

    override fun onBind(intent: Intent?): IBinder? {
        // 서비스에서 gameRepository를 사용
        return null
    }
}

 

@AndroidEntryPoint의 역할

  • @AndroidEntryPoint가 선언된 클래스에서는 해당 클래스가 Hilt에서 의존성 주입을 받을 수 있도록 처리됩니다.
  • Hilt는 해당 컴포넌트가 생성될 때 자동으로 주입할 의존성을 찾아서 삽입합니다.
  • @AndroidEntryPoint가 선언된 컴포넌트에서는 @Inject 어노테이션을 사용하여 의존성을 주입받을 수 있습니다.
  • @AndroidEntryPoint를 사용하면, ViewModel, Repository, Network 모듈 등 필요한 객체들이 컴포넌트에 자동으로 주입되며, 별도의 의존성 생성 코드 없이 DI 패턴을 구현할 수 있습니다.

주의사항

  • @AndroidEntryPoint는 Hilt의 DI 기능을 사용할 수 있는 컴포넌트에서만 사용해야 하며, Activity, Fragment, Service, BroadcastReceiver와 같은 Android 컴포넌트에서 사용됩니다.
  • @AndroidEntryPoint가 없는 컴포넌트에서는 Hilt를 통한 의존성 주입을 사용할 수 없습니다.

요약

@AndroidEntryPoint는 Hilt의 의존성 주입을 Android 컴포넌트에 적용할 때 사용되는 어노테이션으로, 이를 통해 Activity, Fragment, Service 등에서 의존성 주입을 쉽게 할 수 있습니다.

@Provides는 Dagger-Hilt 또는 Dagger에서 사용되는 어노테이션으로, 의존성을 제공하는 메서드를 정의할 때 사용됩니다. 이 어노테이션은 객체 생성 로직을 제공하는 메서드에 붙여주며, Dagger/Hilt가 해당 메서드를 호출하여 필요한 의존성을 주입할 수 있도록 합니다.

 

기본 개념

 

  • @Provides는 Hilt 모듈 안에서 사용되어 특정 타입의 객체를 생성하고, 이 객체를 의존성으로 제공하는 역할을 합니다.
  • Hilt는 @Provides가 붙은 메서드를 통해 의존성을 생성하고, 필요한 곳에 주입합니다.

예시

@Module
@InstallIn(SingletonComponent::class)  // SingletonComponent에 설치
object NetworkModule {

    // ApiService를 제공하는 메서드
    @Provides
    fun provideApiService(): ApiService {
        return Retrofit.Builder()
            .baseUrl("https://api.example.com")
            .addConverterFactory(GsonConverterFactory.create())
            .build()
            .create(ApiService::class.java)
    }
}

 

 

위 코드에서 @Provides 어노테이션은 provideApiService 메서드에 적용되어 ApiService 객체를 생성하고 제공하는 역할을 합니다. Hilt는 ApiService를 요청하는 곳에 해당 객체를 주입할 수 있습니다.

 

@Provides 사용의 필요성

 

  • 자동 객체 생성을 위한 설정: Hilt는 자동으로 객체를 생성하지 않기 때문에, @Provides를 사용하여 객체 생성 방법을 명시해야 합니다. Hilt는 이 메서드를 호출하여 객체를 생성하고, 해당 객체를 필요한 곳에 주입합니다.
  • 매개변수 기반 의존성 제공: 의존성의 매개변수로 다른 객체들이 필요한 경우, @Provides를 사용하여 의존성을 동적으로 제공할 수 있습니다.

매개변수 사용 예시

다른 객체를 주입해야 하는 경우 @Provides 메서드의 매개변수로 의존성을 받을 수 있습니다. Hilt는 이 의존성들을 자동으로 해결하여 @Provides 메서드에 전달합니다.

@Module
@InstallIn(SingletonComponent::class)
object AppModule {

    @Provides
    fun provideUserManager(apiService: ApiService, userPreferences: UserPreferences): UserManager {
        return UserManager(apiService, userPreferences)
    }

    @Provides
    fun provideApiService(): ApiService {
        return Retrofit.Builder()
            .baseUrl("https://api.example.com")
            .addConverterFactory(GsonConverterFactory.create())
            .build()
            .create(ApiService::class.java)
    }

    @Provides
    fun provideUserPreferences(): UserPreferences {
        return UserPreferences()
    }
}

 

 

위 예제에서 provideUserManager 메서드는 ApiService와 UserPreferences 의존성을 매개변수로 받아 UserManager 객체를 반환합니다. Hilt는 이 메서드를 호출할 때 필요한 의존성들을 자동으로 주입합니다.

 

@Provides와 @Inject의 차이

  • @Provides: 의존성 제공 방법을 명시적으로 정의하는 방법입니다. 주로 객체 생성 로직을 포함한 메서드에 사용됩니다.
  • @Inject: 의존성을 자동으로 주입받을 때 사용하는 어노테이션입니다. 주로 클래스의 생성자나 필드에 사용됩니다.

@Inject는 의존성을 주입하는 곳에 사용되며, @Provides는 의존성을 제공하는 곳에 사용됩니다.

 

@Provides와 @Module

  • @Module 어노테이션이 붙은 클래스 안에서 @Provides 메서드를 정의하여, Hilt가 의존성 주입을 처리할 수 있도록 합니다.
  • @Module은 Dagger 또는 Hilt가 객체를 제공할 수 있도록 의존성의 생성 방법을 정의하는 곳입니다.

결론

@Provides는 의존성 객체를 생성하여 제공하는 메서드에 사용됩니다. Hilt는 @Provides로 정의된 메서드를 호출하여 필요한 의존성을 생성하고, 다른 곳에서 이 객체를 주입받을 수 있게 해줍니다. 객체 생성 방법을 명시적으로 제공해야 할 때 @Provides를 사용하며, 이를 통해 의존성 주입의 흐름을 관리합니다.

@InstallIn 어노테이션은 Dagger-Hilt에서 사용되는 어노테이션으로, Hilt 모듈어디에 설치할 것인지 지정하는 역할을 합니다. 이 어노테이션은 Dagger-Hilt에서 DI (Dependency Injection) 설정을 쉽게 해주는 중요한 요소입니다.

 

 

기본 개념

Dagger-Hilt에서는 의존성 주입을 위해 여러 모듈을 정의하고, 이 모듈이 어떤 컴포넌트(범위)에 포함될지 지정해야 합니다. 이때 @InstallIn 어노테이션을 사용하여, 특정 모듈을 어떤 컴포넌트에 설치할 것인지 정의할 수 있습니다. @InstallIn은 기본적으로 @Component 또는 @Subcomponent와 같은 Dagger의 컴포넌트 개념에 대응됩니다.

 

사용 방법

Dagger-Hilt에서는 주로 다음과 같은 컴포넌트를 사용하여 의존성을 주입합니다:

  • SingletonComponent: 애플리케이션의 전체 생애 주기 동안 하나의 인스턴스만 유지되는 컴포넌트입니다.
  • ActivityComponent: 액티비티의 생애 주기 동안 의존성 주입을 관리하는 컴포넌트입니다.
  • FragmentComponent: 프래그먼트의 생애 주기 동안 의존성 주입을 관리하는 컴포넌트입니다.
  • ViewModelComponent: ViewModel의 생애 주기 동안 의존성 주입을 관리하는 컴포넌트입니다.

이 외에도 다양한 생애 주기별 컴포넌트가 존재합니다.

 

예시

1. @InstallIn(SingletonComponent::class)

SingletonComponent에 설치된 모듈은 애플리케이션 전역에서 한 번만 생성되어 사용됩니다. 주로 애플리케이션 단위로 한 번만 생성해야 하는 객체들에 대해 사용합니다.

 
@Module
@InstallIn(SingletonComponent::class)  // SingletonComponent에 설치
object NetworkModule {

    @Provides
    fun provideApiService(): ApiService {
        return Retrofit.Builder()
            .baseUrl("https://api.example.com")
            .addConverterFactory(GsonConverterFactory.create())
            .build()
            .create(ApiService::class.java)
    }
}

 

이렇게 설정하면 ApiService는 애플리케이션의 전체 생애 주기 동안 하나의 인스턴스로만 존재하게 됩니다.

2. @InstallIn(ActivityComponent::class)

ActivityComponent에 설치된 모듈은 액티비티의 생애 주기에 맞춰 의존성을 관리합니다. 즉, 액티비티가 존재하는 동안에만 해당 객체가 존재합니다.

@Module
@InstallIn(ActivityComponent::class)  // ActivityComponent에 설치
object ActivityModule {

    @Provides
    fun provideSomeDependency(): SomeDependency {
        return SomeDependency()
    }
}
 

이렇게 설정하면 SomeDependency는 액티비티가 존재하는 동안에만 사용됩니다.

3. @InstallIn(ViewModelComponent::class)

ViewModelComponent에 설치된 모듈은 ViewModel의 생애 주기 동안에 의존성을 관리합니다. ViewModel이 생성되고 파괴될 때 해당 의존성도 주입되고 파괴됩니다.

 
@Module
@InstallIn(ViewModelComponent::class)  // ViewModelComponent에 설치
object ViewModelModule {

    @Provides
    fun provideGameRepository(): GameRepository {
        return GameRepositoryImpl()
    }
}

이렇게 설정하면 GameRepository는 ViewModel의 생애 주기 동안에만 사용됩니다.

요약

  • @InstallIn 어노테이션은 Hilt 모듈을 특정 컴포넌트에 설치하여 해당 컴포넌트의 생애 주기에 맞는 의존성 관리를 할 수 있게 합니다.
  • SingletonComponent, ActivityComponent, FragmentComponent, ViewModelComponent와 같은 다양한 컴포넌트를 사용하여 의존성의 생애 주기를 조절할 수 있습니다.
  • 이 방식은 Hilt의 의존성 주입을 더 효율적으로 관리할 수 있게 해주며, 주입할 객체의 범위를 명확하게 정의할 수 있게 해줍니다.

코틀린에서도 자바와 같이 함수를 재정의(overriding) 할 수있습니다.

아래의 정리된 내용은 코틀린에서 함수를 재정의 방법을 정리한 내용이다. 

 

* 함수재정의(overriding)

// super class
open class SmartDevice(val name: String, val category: String) {
	
	open fun turnOn() {
	
	}
	
	open fun turnOff() {
	
	}
}

class SmartTvDevice(deviceName: String, deviceCategory: String) :
	SmartDevice(name = deviceName, category = deviceCategory) {

	override fun turnOn() {
		// super.turnOn()
		println("SmartTV Turn On")
	}
	override fun turnOff() {
		// super.turnOff()
		println("SmartTV Turn Off")
	}
}

 

부모 클래스(슈퍼클래스)의 함수를 재정의 할 때는 재정의가 필요한 부모클래스 함수의 이름 앞에 open 키워드를 써준다.

자식 클래스(서브클래스) 앞에는 override 키워드를 입력하면 재정의를 할수 있다.(자바의 override와 같음)

위 소스코드에 자식 클래스의 오버라이드한 함수안에 주석을 제거 할 경우(super.turnOn() or super.turnOff()) 부모 클래스의 함수를 실행 후 자식 클랙스의 함수를 실행한다. super키워드를 사용하지 않을 경우 부모 함수내의 로직은 무시된다.

 

 

* 서브클래스에서 슈퍼클래스 속성 재정의

 

코틀린에서는 속성값에도 재정의를 사용할수 있다.

// super class
open class SmartDevice(val name: String, val category: String) {
	open val deviceType: String = "Unknow"
}

// sub class
class SmartTvDevice(deviceName: String, deviceCategory: String) :
	SmartDevice(name = deviceName, category = deviceCategory) {

	override val deviceType: String = "Smart TV"
}

 

 

코틀린에서 함수 또는 속성값을 재정의하는 것을 알아보았다.

여기서 핵심으로 기억해야 할 것들은 재정의하고자 하는 부모의 함수 또는 속성값 앞에 "open " 키워드를 입력해줘야한다.

또한 재정의하는 자식 클래스의 함수(또는 속성값)앞에 "override" 키워드를 입력해준다.

'Kotlin' 카테고리의 다른 글

[코틀린] 스코프란? - 개념 이해하기  (0) 2024.11.22
[코틀린] suspend란? - 비동기 작업 처리  (0) 2024.11.14

자바 스크립트는 별도의 환경 설정을 필요하지는 않다(언어만을 배우기위해서는). 실제 코드를 작성 할 IDE 툴을 설치하면 언어를 공부하는데 충분합니다.

 

Visual Studio Code 설치 하기

https://code.visualstudio.com/

 

Visual Studio Code - Code Editing. Redefined

Visual Studio Code is a code editor redefined and optimized for building and debugging modern web and cloud applications.  Visual Studio Code is free and available on your favorite platform - Linux, macOS, and Windows.

code.visualstudio.com

 

위 해당 사이트에 가면 무료로 다운로드 받아 사용할 수 있습니다.

 

아래의 이미지 처럼 사이트에 방문하게 되면, 메인 페이지에 해당 OS에 맞춰 다운로드할 수 있도록 나옵니다.

또는 DOWNLOAD 페이지로 이동하여 OS에 맞는 버전을 선택하여 설치하여 사용하면 됩니다.

 

 

 

아래의 이미지는 DOWNLOAD 페이지에 가면 OS에 맞는 파일을 다운로드 할 수 있습니다.

 

 

 

+ Recent posts