1.  오브젝트  Object

👩🏻‍💻  오브젝트 object를 사용하면 클래스를 생성자로 인스턴스화 하지 않아도 블록 안의 프로퍼티와 메서드를 호출해서 사용할 수 있다.  ➡️ 자바의 static과 같은 역할
👩🏻‍💻  object 코드 블록 안의 프로퍼티와 메서드는 클래스명에 점 연산자를 붙여서 생성자 없이 직접 호출
👩🏻‍💻  주의할 점은 클래스명을 그대로 사용하기 때문에 호출하는 클래스명의 첫 글자가 대문자


1) 컴패니언 오브젝트


  👾  일반 클래스에 object 기능을 추가하기 위해서 사용
  👾  클래스 코드 안에 companion object 블록으로 감싸주면 생성 과정 없이 오브젝트처럼 사용할 수 있음

object Cat {
    var name: String ="pinky"
    fun printName() {
        println("Cat의 이름은 ${name}입니다.")
    }
}

class Dog {
    companion object {
        var name: String = "None"
        fun printName() {
            println("Dog 이름은 ${name}입니다.")
        }
    }
    fun walk() {
        println("Dog가 뛰어갑니다.")
    }
}

fun main() {
    Cat.name = "mikey"
    Cat.printName() // Cat의 이름은 mikey 입니다.

    // companion object 안의 코드 사용하기
    Dog.name = "Linda"
    Dog.printName() // Dog 이름은 Linda 입니다.
    //Dog.walk() companion object 밖에 선언된 메소드는 사용하지 못함

    // companion object 밖의 코드 사용하기
    val dog = Dog()
    dog.walk() // Dog가 뛰어갑니다.

}

 


2.  데이터 클래스

👩🏻‍💻  코틀린은 간단한 값의 저장 용도로 데이터 클래스 data class를 제공

data class 클래스 이름 (val 파라미터1: 타입, var 파라미터2: 타입)


  ✏️  데이터 클래스를 정의할 때 class 앞에 data 키워드를 사용해야 하고, 생성자 파라미터 앞에 입력하는 var 또는 val 키워드를 생략할 수 없음
  ✏️  생성하는 코드는 일반 클래스와 동일하게 작성

fun main() {
    // 정의 - 주로 코드 블록(클래스 스코프)을 사용하지 않고 간단하게 작성.
    data class UserData(val name: String, var age: Int)

    // 생성 - 일반 class의 생성자 함수를 호출하는 것과 동일
    val userData = UserData("Michael", 21)

    //userData.name = "Cindy" // val로 선언되었기 때문에 변경 불가능

    userData.age = 19 // var로 선언되었기 때문에 변경 가능
}

1) toString() 메소드와 copy() 메소드


  👾  일반 클래스에서 toString() 메소드를 호출하면 인스턴스의 주소값을 반환하지만, 데이터 클래스는 값을 반환하기 때문에 실제 값을 모니터링 할 때 좋음

    println("userData는 ${userData}") // userData는 UserData(name=Michael, age=19)
    println(userData.toString()) // UserData(name=Michael, age=19)

 

  👾  copy() 메소드로 간단하게 값을 복사할 수 있음

    var newData: UserData = userData.copy()

 

  👾  이처럼 클래스와 사용법이 동일하지만 주로 네트워크를 통해 데이터를 주고 받거나, 혹은 로컬 앱의 데이터베이스에서 데이터를 다루기 위한 용도로 사용

 

데이터 클래스는 toString(), copy()와 같은 메소드를 자동으로 만들어줌
    * toString() : 객체에 포함되어 있는 데이터를 출력하여 볼 수 있음. 생성자에 포함된 프로퍼티만 출력.
    * copy() : 객체의 속성들을 복사하여 반환하는 메소드이며 인수로 받은 프로퍼티만 해당 값으로 바뀌어 복사해줌
fun main() {

    data class Memo(val title: String, val content: String, var isDone: Boolean)
    val memo1 = Memo("마트 가기", "계란, 우유, 빵", false)

    val memo2 = memo1.copy(content="칫솔, 과자") // content 프로퍼티만 변경
    println(memo1.toString()) // Memo(title=마트 가기, content=계란, 우유, 빵, isDone=false)
    println(memo2.toString()) // Memo(title=마트 가기, content=칫솔, 과자, isDone=false)

}

 

 


3.  클래스의 상속과 확장

1) 클래스의 상속

 

👩🏻‍💻  상속을 사용하면 부모 클래스의 프로퍼티를 마치 내 클래스의 일부처럼 사용할 수 있음

      상속을 사용하는 예를 들면 안드로이드는 Activity라는 클래스가 미리 만들어져 있고, 이 Activity 클래스 내부에는 글자를 쓰는 기능, 그림을 그리는 기능, 화면에 새로운 창을 보여주는 기능이 미리 정의되어 있음. 상속이 있기에 이런 기능을 직접 구현하지 않고 Activity 클래스를 상속받아 약간의 코드만 추가하면 앱에 필요한 기능을 추가할 수 있음.

 

👩🏻‍💻  코틀린에서 클래스를 상속받으려면 부모 클래스에 open 키워드를 추가해야 함

       ✓ 상속을 받을 자식 클래스에서는 콜론을 이용해서 상속할 부모 클래스를 지정 .다음에 괄호를 입력해서 꼭 부모의 생성자를 호출

    open class 상속될 부모 클래스 {
        // 코드
    }

    class 자식 클래스 : 부모 클래스() {
        // 코드
    }


👩🏻‍💻  메소드도 자식 클래스에서 오버라이딩하려면 부모 클래스의 메소드에 open 키워드를 추가

fun main() {

    open class Flower {
        open fun waterFlower() {
            println("water flower")
        }
    }
    // 콜론 : 을 이용해 상속을 나타내면 됨
    class Rose: Flower() {
        override fun waterFlower() {
            super.waterFlower()
            println("Rose is water flower")
        }
    }

    val rose = Rose() // 객체 생성
    rose.waterFlower() // Rose is water flower

}

 



A. 생성자가 있는 클래스의 상속


👩🏻‍💻  상속될 부모 클래스의 생성자에 파라미터가 있다면 자식 클래스를 통해 값을 전달할 수 있음

   open class 상속될 부모 클래스(value : String) {
        // 코드
    }

    class 자식 클래스(value : String) : 부모 클래스(value) {
        // 코드
    }


   👾 부모 클래스에 세컨더리 생성자가 있다면, 자식 클래스의 세컨더리 생성자에서 super 키워드로 부모 클래스에 전달할 수 있음
   👾 부모 클래스의 세컨더리 생성자를 이용하는 경우에는 부모 클래스명 다음에 오는 괄호를 생략

 


B. 부모 클래스의 프로퍼티와 메서드 사용하기


👩🏻‍💻  부모 클래스에서 정의된 프로퍼티와 메서드는 내 것처럼 사용할 수 있음

    open class Parent {
        var hello: String = "안녕하세요"
        fun sayHello() {
            println(hello)
        }
    }

    class Child: Parent() {
        fun myHello() {
            hello = "Hello"
            sayHello()
        }
    }

    val child = Child()
    child.myHello() // Hello

2) 익스텐션


코틀린은 클래스, 메서드, 프로퍼티에 대해 익스텐션 extensions 을 지원
이미 만들어져 있는 클래스에 다음과 같은 형태로 추가할 수 있음

    fun 클래스.확장할 메서드() {    // 코드    }*

 

    👾  상속이 미리 만들어져 있는 클래스를 가져다 쓰는 개념이라면 익스텐션은 미리 만들어져 있는 클래스에 메서드를 넣는 개념
           ✓ 자신이 만든 클래스에 사용하기 보다는 이미 컴파일되어 있는 클래스에 메서드를 추가하기 위한 용도로 사용
    👾  실제 클래스의 코드가 변경되는 것은 아니며 단지 실행 시에 점 연산자로 호출해서 사용할 수 있도록 해줌

아래 코드는 기본 클래스인 String에 plus 메서드를 확장하는 코드
test 함수에 선언한 original에 문자열을 입력했기 때문에 original은 String의 익스텐션 메서드인 plus를 호출해서 사용
fun main() {

    fun String.addText(word: String) : String {
        return this + word
    }

    fun testStringExtension() {
        val original = "Hello"
        val added = "Guys~"

        println("added를 더한 값은 ${original.addText(added)}입니다.")
    }

    testStringExtension() // added를 더한 값은 HelloGuys~입니다.

}

 

 

[ 내용 참고 : IT 학원 강의 ]

+ Recent posts