본문 바로가기
프로그래밍/Kotlin

[Kotlin 기초 2] Objects (1)

by 채연2 2023. 2. 9.

 

기초 1에서는 기본 구문에 대해 알아보았고, 기초 2에서는 Object에 대해 간략하게 학습해 보려고 한다.

 

Contents

     

     

    Objects

    Object는 속성(val, var)을 사용하여 데이터를 저장하고 함수를 사용하여 이 데이터로 작업을 수행한다.

    • Class : 새로운 데이터 유형에 대한 속성 및 기능 정의. 사용자 정의 유형
    • Member : 클래스 속성 또는 함수
    • Member function : 특정 object 클래스에서만 작동하는 함수
    • Creating an object : 클래스의 val 또는 var 생성. 해당 클래스의 인스턴스 생성

    Class

     

        fun objectTest() {
            val r1 = IntRange(0, 10)
            val r2 = IntRange(5, 7)
            Log.e("KotlinTest", "r1 : $r1")
            Log.e("KotlinTest", "r2 : $r2")
        }

     

    IntRange는 클래스이지만, 0에서 10까지의 특정 범위인 r1은 5에서 7까지의 특정 범위인 r2와는 다른 개체이다.
    또, IntRange은 일종의 object이며 object의 정의 특성은 작업을 수행한다는 것이고, 작업 수행 대신에 멤버 함수 호출이라고 할 수 있다.

     

    object에 대한 멤버 함수를 호출하려면 object 식별자 - 점(dot) - 작업 이름으로 호출한다.

     

        fun objectTest() {
            val r = IntRange(0, 10)
            Log.e("KotlinTest", "sum : ${r.sum()}")
        }

     

    클래스는 많은 작업(멤버 함수)을 가질 수 있고, 코드 완성이라는 기능이 포함된 IDE를 사용하여 클래스를 보다 쉽게 탐색 가능하다.

     

    object 식별자 뒤에 .s를 입력하면 s로 시작하는 해당 object의 모든 구성원이 표시된다. (만일 표시되지 않는 경우, 스페이스바 + Ctrl키를 눌러주면 된다)

     

     

    Creating Classes

    앞서 예를 들었던 IntRange와 같은 미리 정의된 유형의 클래스를 사용할 수 있을 뿐만 아니라 고유한 유형의 object를 직접 생성할 수도 있다.

     

    class Giraffe
    class Bear
    class Hippo
    
    fun classTest() {
       val g1 = Giraffe()
       val g2 = Giraffe()
       val b = Bear()
       val h = Hippo()
    
       Log.e("cylog", "$g1")
       Log.e("cylog", "$g2")
       Log.e("cylog", "$h")
       Log.e("cylog", "$b")
    }

    클래스를 정의하려면 class 키워드로 시작하고 그 뒤에 새 클래스의 식별자(클래스 명)가 온다. 클래스 명은 규칙에 따라 첫 글자는 대문자로, 모든 val과 var의 첫 글자는 소문자로 작명한다.

     

    출력된 로그를 보면 @ 앞부분은 클래스 이름이고, @ 뒷부분은 컴퓨터 메모리에서 객체가 위치한 주소를 뜻하고 16진수로 표기되어 있다. 프로그램의 모든 object에는 고유한 주소가 존재한다.

     

    위에서 생성한 클래스는 간단하게 한 줄로 정의되어 있지만, 해당 클래스의 특성과 동작을 포함하는 좀 더 복잡한 클래스로 정의하고 싶다면 중괄호({})를 사용하여 생성하면 된다.

     

    class Dog {
       fun bark() = "yip!"
    }
    class Cat {
       fun meow() = "mrrrow!"
    }
    
    fun classTest() {
       val dog = Dog()
    
       val cat = Cat()
       val m1 = cat.meow()
       Log.e("cylog", "m1 : $m1")
    }

    Dog 클래스의 객체를 생성하고 val dog에 할당했지만 dog를 사용하지 않았기 때문에 Kotlin은 "Variable 'dog' is never used."라는 경고를 내보낸다.

     

    멤버 함수를 호출할 때 Kotlin은 해당 object에 대한 참조를 자동으로 전달하여 관심 있는 object를 추적한다. 해당 참조는 this 키워드를 사용하여 멤버 함수 내에서 사용 가능하다.

     

    class Hamster {
       fun speak() = "Squeak! "
       fun exercise() = this.speak() + speak() +
                      "Running on wheel"
    }
    
    fun classTest() {
       val hamster = Hamster()
       Log.e("cylog", hamster.exercise())
    }

    멤버 함수는 해당 요소의 이름을 지정하기만 하면 클래스 내 다른 요소에 대한 특별한 접근 권한을 가지고, 이를 사용하여 해당 요소에 대한 접근을 명시적으로 한정할 수도 있다. 위 예제에서 exercise()는 this 키워드에 관계없이 speak()를 호출한다. 

     

    Properties

    속성 Property는 클래스의 일부인 var 또는 val을 의미한다. 속성을 정의하면 클래스 내에서 상태가 유지되며, 상태가 유지된다는 것은 하나 이상의 독립적으로 실행되는 함수를 작성하는 것보다 클래스를 만드는 주된 이유이다.

     

    var 속성은 재할당이 가능하지만 val 속성은 재할당이 불가능하다. 각 object는 속성에 대한 자체 저장소를 가진다.

     

    class Cup {
       var percentFull = 0
    }
    
    fun classTest() {
       val c1 = Cup()
       c1.percentFull = 50
       val c2 = Cup()
       c2.percentFull = 100
    
       Log.e("cylog", "c1 : ${c1.percentFull}")
       Log.e("cylog", "c2 : ${c2.percentFull}")
    }

    Cup 클래스 내 percentFull 속성은 해당 Cup object의 상태를 나타낸다. c1.percentFull과 c2.percentFull은 서로 다른 값을 포함하며 각 object에 고유한 저장소를 가짐을 보여준다.

     

    class Cup2 {
       var percentFull = 0
       val max = 100
       fun add(increase: Int): Int {
          percentFull += increase
          if (percentFull > max)
             percentFull = max
          return percentFull
       }
    }
    
    fun classTest() {
       val cup = Cup2()
       cup.add(50)
       Log.e("cylog", "1 cup : ${cup.percentFull}")
       cup.add(70)
       Log.e("cylog", "2 cup : ${cup.percentFull}")
    }

    멤버 함수 내에서는 해당 클래스 내 속성을 점 표기법을 사용하지 않고 바로 참조 가능하다. 

     

    Constructors

    생성자에 정보를 전달하여 새 객체를 초기화할 수 있다.

     

    class Alien(name: String) {
       val greeting = "Poor $name!"
    }
    
    fun classTest() {
       val alien = Alien("Mr. Meeseeks")
       Log.e("cylog", alien.greeting)
    }

    Alien 클래스의 생성자는 단일 인자를 사용하여 초기화한다. 인자인 name은 생성자 내에서 greeting 속성을 초기화 하지만, 생성자 외부에서는 접근할 수 없다.

     

    클래스 외부에서 생성자 매개변수에 접근할 수 있도록 하려면 매개변수 목록에서 var 또는 val로 정의하면 된다.

     

    class MutableNameAlien(var name: String)
    class FixedNameAlien(val name: String)
    
    fun classTest() {
       val alien1 =  MutableNameAlien("Reverse Giraffe")
       val alien2 =  FixedNameAlien("Krombopulos Michael")
    
       alien1.name = "Parasite"
       Log.e("cylog", "alien1 : ${alien1.name}")
       Log.e("cylog", "alien2 : ${alien2.name}")
    }

    toString() 멤버 함수는 문자열이 필요할 때 호출되는 함수이다. toString을 호출하지 않고 클래스 객체만 호출해도 기본적으로 toString 멤버 함수가 호출이 된다. 하지만 기본 toString 멤버 함수는 클래스 이름과 객체의 물리적 주소를 생성해서 그다지 유용하지 않기에 자신만의 toString() 함수를 정의할 수 있다.

     

    toString 함수에는 기본 결과를 생성하는 정의가 이미 존재하기에 override 키워드가 필요하다. override 키워드의 명시성은 코드를 명확하게 하고 실수를 방지할 수 있게 해준다.

     

    class Scientist1(val name: String)
    class Scientist2(val name: String) {
       override fun toString(): String {
          return "Scientist('$name')"
       }
    }
    
    fun classTest() {
       val zeep1 = Scientist1("Zeep Xanflorp")
       val zeep2 = Scientist2("Zeep Xanflorp")
       Log.e("cylog", "zeep1 : $zeep1")
       Log.e("cylog", "zeep2 : $zeep2")
    }

     

     

     

    320x100

    '프로그래밍 > Kotlin' 카테고리의 다른 글

    [Kotlin 기초 2] Objects (3)  (9) 2023.02.17
    [Kotlin 기초 2] Objects (2)  (6) 2023.02.09
    [Kotlin 기초 1] 기본 구문 (3)  (4) 2023.02.07
    [Kotlin 기초 1] 기본 구문 (2)  (7) 2023.02.07
    [Kotlin 기초 1] 기본 구문 (1)  (2) 2023.02.03

    댓글