[Kotlin] Functions, Variables, Null Safety, Classes, Generics, Inheritance

Kotlin Functions, Variables, Null Safety, Classes, Generics, Inheritance에 대해서 알아봅니다.
Apr 19, 2024
[Kotlin] Functions, Variables, Null Safety, Classes, Generics, Inheritance

Introduction

Hello World

  1. Kotlin 코드는 일반적으로 패키지로 정의됩니다. 패키지 지정은 선택 사항입니다. 소스 파일에 패키지를 지정하지 않으면 해당 콘텐츠는 기본 패키지로 이동합니다.

  2. Kotlin 애플리케이션의 진입점은 주요 기능입니다. 매개 변수 없이 선언할 수 있습니다. 반환 유형이 지정되지 않았으므로 함수가 아무 것도 반환하지 않습니다.

  3. println은 표준 출력에 한 줄을 씁니다. 이 함수는 암시적으로 가져옵니다. 또한 코드 줄 끝에 세미콜론은 선택 사항입니다.

Functions

Default Parameter Values(기본값 매개변수) 그리고 Named Arguments(명명된 인수)

  1. printMessageWithPrefix(message: String, prefix: String = "Info") 는 기본값이 Info인 두번째 선택적 매개변수를 받는 함수이다. 반환 유형이 생략되어 실제로는 Unit이다.

  2. printMessageWithPrefix(prefix = "Log", message = "Hello") 는 named arguments를 사용하고 인수의 순서를 변경하여 함수를 호출한다.

  3. 매개변수의 기본값은 값일 필요는 없다. 다른 함수일 수도 있다.

fun shouldChangeWater (
    day: String, 
    temperature: Int = 22, 
    dirty: Int = getDirtySensorReading()): Boolean {
    ...

기본값으로 사용되는 함수는 런타임 시 평가되므로 파일 읽기나 대용량 메모리 할당과 같은 비용이 많이 드는 작업을 함수에 넣지 마십시오. 함수가 호출될 때마다 작업이 실행되므로 프로그램 속도가 느려질 수 있습니다.

Infix Functions (접미사 함수)

  1. times 라는 이름의 중위함수를 정의한다. Int 클래스의 확장 함수로, 문자열과 함께 사용된다. 이 함수는 주어진 문자열을 현재 정수만큼 반복하여 반환한다. Bye Bye가 출력된다.

  2. to 함수를 사용하여 "Ferrari"와 "Katrina"라는 두 문자열을 Pair로 묶어 pair에 할당한다. to는 코틀린에서 제공하는 중위 함수로, 두 객체를 Pair로 묶는데 사용된다. (Ferrari, Katrina)가 출력된다.

  3. 사용자 정의 중위 함수를 정의하고 사용하는 예이다. onto라는 이름의 중위 함수를 정의한다. 이 함수는 String 클래스의 확장 함수로, 다른 String과 함께 사용할 수 있다. 이 함수는 두 문자열을 Pair로 묶어 반환한다.
    "McLaren" 과 "Lucas"라는 두 문자열을 Pair로 묶어 myPair에 할당한다. 출력하면 (McLaren, Lucas)이 출력된다.

  4. Person클래스는 name이라는 속성을 가진다. Person객체가 좋아하는 사람들의 목록을 저장하는 likedPeople이라는 MutableList를 정의한다. sophia, claudia는 Person클래스의 인스턴스를 생성한다.
    likes함수를 사용하여 sophia가 claudia를 좋아한다는 정보를 likedPeople 목록에 추가한다. 이 때 likes함수는 중위 표기법을 사용하여 호출된다.

Kotlin은 다른 함수 내부의 함수인 로컬 함수(다른 함수 안에 중첩된 함수)를 지원한다.

Operator Functions

이것은 앞선 중위 함수를 한 단계 더 나아가 연산자 수정자를 사용한다. times()의 연산자 기호는 *이므로2 * "Bye"를 사용하여 함수를 호출할 수 있다. 연산자 함수는 문자열에 쉽게 범위 접근을 가능하게 한다. get() 연산자는 대괄호 접근 구문을 가능하다.

Functions with vararg Parameters

vararg 매개변수(쉼표)로 구분하여 인수를 여러 개 전달할 수 있다.

vararg 수정자는 매개변수를 가변 인자로 변환합니다. 이를 통해 printAll 함수를 임의의 개수의 문자열 인자와 함께 호출할 수 있습니다.

이름이 지정된 매개변수 덕분에, 가변 인자 뒤에 같은 타입의 다른 매개변수를 추가할 수 있습니다. 이는 자바에서는 값을 전달하는 방법이 없기 때문에 허용되지 않습니다.

이름이 지정된 매개변수를 사용하면, 가변 인자와 별개로 prefix에 값을 설정할 수 있습니다. 런타임에는 가변 인자는 단지 배열일 뿐입니다.

이를 가변 인자 매개변수로 전달하려면, entries(Array<String>) 대신에 *entries (vararg of String)를 전달할 수 있게 해주는 특별한 스프레드 연산자 * 를 사용합니다.

Variables

Kotlin에는 강력한 유형 추론 기능이 있습니다. 변수의 유형을 명시적으로 선언할 수도 있지만, 일반적으로 컴파일러가 유형을 추론하여 작업을 수행하도록 합니다. Kotlin은 불변성을 강제하지는 않지만 권장합니다. 본질적으로 var보다 val을 사용하세요.

Null Safety

소프트웨어의 널 포인터 예외로 인해 금전적 손실이 발생하고 엄청난 컴퓨터 충돌이 발생했으며 수많은 디버깅 시간이 소요되었습니다.

따라서 Kotlin은 null을 허용하는 데이터 유형과 null을 허용하지 않는 데이터 유형을 구별하여 컴파일 타임에 더 많은 오류를 포착하는 데 도움이 됩니다.

Kotlin은 강력한 유형을 사용하므로 코드에서 유형을 추론하는 데 많은 작업을 수행합니다. 여기에는 람다, 코루틴 및 속성이 있어 더 적은 버그로 더 적은 코드를 작성할 수 있습니다.

5-6) 추론된 타입에 대해서, 값으로 초기화 된 변수에 대해서non-null 을 가정한다. 즉, null이 아닌 것으로 가정한다. 유형이 추론된 변수에 null을 할당하려고 하면 컴파일 오류가 발생한다.

NullPointerException을 없애기 위해 Kotlin의 변수 유형은 null 할당을 허용하지 않습니다. 널이 될 수 있는 변수가 필요한 경우 변수 유형 끝에 ? 을 추가하여 널 가능으로 선언하세요.

Working with Nulls (널과 작업하기)

외부 Java 코드와 상호 작용하거나 실제로 존재하지 않는 상태를 표현할 때와 같이 Kotlin 프로그램에서 null 값으로 작업해야 하는 경우가 있다. Kotlin은 이러한 상황을 우아하게 처리하기 위해 널 추적을 제공한다.

  1. nullable한 문자열을 받아 해당 설명을 반환하는 함수

  2. 만약 주어진 문자열이 null이 아니고 비어 있지 않으면 길이에 대한 정보를 반환한다.

  3. 그렇지 않으면, 호출자에게 문자열이 비어있거나 null이라고 알려준다.

Classes

클래스 선언은 클래스 이름, 클래스 헤더(유형 매개변수, 기본 생성자 등을 지정), 중괄호로 둘러싸인 클래스 본문으로 구성됩니다. 헤더와 본문은 모두 선택 사항이며, 클래스에 본문이 없는 경우 중괄호를 생략할 수 있습니다.

visibility modifiers

지금까지 코드에는 public 또는 private와 같은 visibility modifiers가 없었습니다. 그 이유는 기본적으로 Kotlin의 모든 것이 공용이므로 클래스, 메서드, 속성 및 멤버 변수를 포함하여 모든 곳에서 액세스할 수 있기 때문입니다.

Kotlin에서는 클래스, 개체, 인터페이스, 생성자, 함수, 속성 및 해당 설정자에 visibility modifiers를 가질 수 있습니다

  • public 은 클래스 외부에서 볼 수 있음을 의미한다. 클래스의 변수와 메서드를 포함한 모든 것이 기본적으로 공개된다.

  • internal 은 해당 모듈 내에서만 볼 수 있음을 의미한다. 모듈은 라이브러리 또는 애플리케이션과 같이 함께 컴파일된 Kotlin 파일 집합이다.

  • private 은 해당 클래스(또는 함수로 작업하는 경우 소스 파일)에서만 볼 수 있음을 의미한다.

  • protected 은 비공개와 동일하지만 모든 하위 클래스에서도 볼 수 있습니다.

Member variables

클래스 내의 속성 또는 멤버 변수는 기본적으로 공용이다. var로 정의하면 변경 가능, 즉 읽기 및 쓰기가 가능합니다. val로 정의하면 초기화 후 읽기 전용이 됩니다.

내 코드에서는 읽거나 쓸 수 있지만 외부 코드에서는 읽기만 가능한 프로퍼티를 원하는 경우 아래와 같이 속성과 해당 getter를 공개로 두고 setter를 비공개로 선언할 수 있습니다.

var volume: Int
    get() = width * height * length / 1000
    private set(value) {
        height = (value * 1000) / (width * length)
    }

Generics

제네릭은 현대 언어에서 표준이 된 범용성 메커니즘입니다. 제네릭 클래스와 함수는 특정 제네릭 유형과 독립적인 공통 로직을 캡슐화하여 코드 재사용성을 높입니다(예: List<T> 내부의 로직은 T가 무엇인지와 독립적인 것처럼).

Kotlin에서 제네릭을 사용하는 첫 번째 방법은 Generic Classes를 만드는 것입니다.

  1. 제네릭 클래스 MutableStack<E>를 정의하며, 여기서 E는 제네릭 타입 매개변수라고 합니다. 사용할 때는 MutableStack<Int>를 선언하여 Int와 같은 특정 유형에 할당됩니다.

  2. 제네릭 클래스 내에서 E는 다른 타입과 마찬가지로 파라미터로 사용할 수 있습니다.

  3. E를 반환 유형으로 사용할 수도 있습니다.

Inheritance

Kotlin은 기존의 객체 지향 상속 메커니즘을 완벽하게 지원합니다.

Kotlin 클래스는 기본적으로 final입니다. 클래스 상속을 허용하려면 클래스에 open 수정자를 표시하세요.

Kotlin 메서드도 기본적으로 final입니다. 클래스와 마찬가지로 open 수정자를 사용하면 메서드를 재정의할 수 있습니다.

클래스 이름 뒤에 : SuperclassName()을 지정하면 클래스가 수퍼클래스를 상속합니다. 빈 괄호()는 슈퍼클래스 기본 생성자의 호출을 나타냅니다.

Overriding methods나 속성을 재정의하려면 override 수정자가 필요합니다.

Inheritance with Parameterized Constructor

서브클래스를 생성할 때 슈퍼클래스의 매개변수화된 생성자를 사용하려면 서브클래스 선언에 생성자 인수를 제공하세요.

  1. namevarval도 아니다. 생성자 인자이며, 그 값은 슈퍼클래스 Lion의 name 속성으로 전달된다.

  2. Rufo라는 이름의 Asiatic 인스턴스를 생성합니다. 이 호출은 인자 RufoIndia를 사용하여 Lion 생성자를 호출합니다.

본 포스팅은 Kotlin 공식 문서의 내용을 번역하였습니다.

Share article

code-with-me