IT/Android(비공개)

3. Kotlin(코틀린)_2

상짱 2020. 2. 26. 17:07
반응형

- 클래스(Class)

- 테스트케이스

- ~(test) 패키지는 안드로이드 기능과 상관없는 java or kotlin 코드를 테스트

- ~(androidTest) 패키지는 안드로이드 환경과 연관된 코드를 테스트

package com.example.kotlinsample

import org.junit.Assert
import org.junit.Test

class KotlinTest {

    @Test
    fun test1(){
    	// 예측결과와 실제결과가 동일하지 않는다면 테스트를 실패시키는 함수
        Assert.assertEquals(4, 2 + 2)
    }
}

 

- 프로퍼티(Property) / 필드(Field)

- 필드(Field)는 클래스에 선언되어 있는, 클래스 변수가 아닌 인스턴스 변수를 의미

- 프로퍼티(Property)는 Field와 외부에서 접근 가능한 Getter 또는 Setter 가 있는 경우 / Field 와 접근 가능한 Getter, Setter의 조합

- 코틀린은 실제로 Field 를 사용하지 않는다.

class Test(val name: String) {
    // 나이
    var age: Int = 0

    // 닉네임 - 소문자만 허용
    var nickname: String = ""
        set(value) {
            // field 는 Setter 의 대상이 되는 field 를 의미
            field = value.toLowerCase()
        }
}

 

- 클래스 상속

- 코틀린의 클래스는 기본적으로 상속이 불가

- 상속은 반복되는 중복 코드를 줄여 주는 객체 지향 프로그래밍 핵심 기법

- 2가지 측면에서 접근 가능 

- 코드 구현에 대한 상속 / 인터페이스 집합에 대한 상속

- 인터페이스 상속은 다중 상속에서 자유롭지만 구현 상속은 다중 상속을 하는 경우 문제점이 생긴다.

- 취약한 기반 클래스 문제( fragile base class ) : 하위 클래스에서 상위 클래스의 메소드를 오버라이딩하면서 발생하며, 클래스를 사용하는 코드에서는 클래스의 실제 구현에는 관심을 가지지 않아야 하기 때문

- 캡슐화의 주요 목적 중 하나는 클래스를 사용하는 측면에서 해당 클래스의 구체적인 사항을 모르게 하는 것

- 구체적인 구현 클래스를 알아야만 한다면, '캡슐화가 깨졌다' 라고 본다.

- java 에서 상속을 금지하려면, final 키워드 사용 / public final class ~ / final public int ~

- 코틀린은 상속 불가 / 허용하려면 open 키워드 사용 / open class ~ / open fun ~

 

- 클래스 위임

- 객체 지향에서 위임이란 클래스의 특정 기능들을 대신 처리해 주는 것

- 위임은 코드를 재사용하면서도 취약한 기반 클래스 문제( fragile base class ) 를 해결할 수 있는 방법 중 하나.

- 데코레이터( Decorator ) 패턴 : 특정 클래스의 기능에 추가 기능을 덧붙이는 방법

// Decorator pattern
// ISword.java
public interface ISword {
    public void equip();
}

// Sword.java
public class Sword implements ISword {

    String name;

    public Sword(String name) {
        this.name = name;
    }

    @Override
    public void equip() {
        System.out.println( name + "검~" );
    }

}

// MagicSword.java
public class MagicSword implements ISword {

    ISword iSword;

    public MagicSword(ISword iSword) {
        this.iSword = iSword;
    }

    @Override
    public void equip() {

        play();

        iSword.equip();
    }

    public void play() {
        System.out.println("play~");
    }


    public static void main(String[] args) {
        Sword sword = new Sword("마법");
        new MagicSword(sword).equip();
    }

}

 

- 코틀린은 'by' 키워드를 사용하여 위임을 쉽게 할 수 있다.

class DelegatingArrayList<T>(val innerList: MutableCollection<T> = mutableListOf()) : MutableCollection<T> by innerList {
...
}

 

- 프로퍼티 위임

- Getter, Setter 연산자를 위임할 수 있게 해주며, 3가지 방법을 제공

- lazy properties : 값의 초기화를 처음 프로퍼티를 사용할 때 초기화( lazy )

- observable properties : 프로퍼티에 값이 변경되면 옵저버에게 알려 줍니다.( observable )

- storing properties : 필드가 아닌 맵에 속성을 저장( map )

class DelegateString {
    // Setter 에서 호출된 값을 저장할 변수
    var text = ""

    operator fun getValue( thisRef: Any?, property: KProperty<*>): String {
        return text
    }

    operator fun setValue thisRef: Any?, property: KProperty<*>, value: String): String {
        // 대문자로 변경하여 저장
        text = value.toUpperCase()
        // Setter 에 호출될 때의 문자열과 변경 후 문자열을 프린트
        println( "$value ==> ${text}" )
    }
}

class User {
    // 닉네임은 DelegateString 클래스에 위임
    var nickname by DelegateString()

    // lay 위임은 val 키워드로 선언되어야만 가능함
    val httpText by lazy {
        println("lazy init start")
        InputStreamReader(URL("https://..").openConnection().getInputStream()).readText()
    }

    // name 프로퍼티 값이 변경될 때 마다 자동으로 observable 의 코드가 실행된다.
    var name:String by Delegates.observable(""){
        property, oldValue, newValue ->
        println( "기존값: ${oldValue}, 새로적용될값: ${newValue}" )
    }
}

// Animal 클래스는 map 객체를 생성자에서 받는다.
class Animal(val map:MutableMap<String, Any?>) {
    // 프로퍼티를 map 객체로 위임한다.
    // map 객체에서 값을 읽고, 값을 변경하는 map 객체에서 값이 변경된다.
    var name:String by map
    var age:Int by map
}

- operator : 연산자를 의미

 

- Singleton 패턴 : 객체의 생성을 제한하여 한 개의 인스턴스만 생성되도록 하는 것

- object 키워드 : 해당 클래스가 싱글턴임을 알려준다.

object SingletonKotlin {
	fun log(text:String){
    	println(text)
    }
}

 

- data 키워드 : toString() , eqauls(), hashCode() 등의 함수를 자동으로 생성해 주는 Data클래스를 지원

data class Test( var name:String , var des:String )

 

- 클래스의 가시성 변경자

- 클래스의 메소드 혹은 필드에 대해 접근을 허용하는지 결정하는 역할

- java ------------------------------------------------------------------

- default( 기본 가시성 ) : 같은 패키지에서 접근 가능

- private : 클래스 내부에서만 사용 가능하며 외부에 비공개

- protected : 클래스와 상속받은 하위 클래스에서만 사용 가능

- public : 외부에서 모두 접근 가능

- kotlin ------------------------------------------------------------------

- internal : 같은 모듈에서 접근 가능 -> 자바에서는 public 으로 인식

- private : 같은 파일에서만 접근 가능

- protected : 최상위 선언에서는 사용 불가

- public( 기본 가시성 ) : 모든 곳에서 접근 가능

 

- 모듈 : 한꺼번에 컴파일되어 묶이는 하나의 프로젝트 단위

 

- 내부 클래스와 중첩 클래스

- 내부 클래스 : 클래스 내부에 그냥 class 를 선언하는 경우

- 중첩 클래스 : static 이 붙은 경우

- 차이점 : 외부에 있는 클래스와 생명 주기가 같은가 아닌가 로 구분

- 코틀린은 클래스 내부에 클래스를 선언하는 경우 중첩 클래스가 된다.

- 코틀린에서 내부 클래스로 선언하기 위해서는 inner class 로 선언

class Test {
	val field1 = 0
    
    // 코틀린은 내붕 클래스를 선언하면 중첩클래스가 됨
    class NestedClass {
    	// 중첩 클래스에서는 외부 클래스 속성에 접근 불가
        // val myField = field1
    }
    
    inner class InnerClass {
    	// 내부 클래스에서는 외부 클래스의 속성에 접근 가능
        val myField = field1
    }
}

 

 

* 코틀린에서 클래스의 프로퍼티는 val 의 경우 Getter 가, var 의 경우 Getter, Setter 가 자동 생성된다.

* 필드란 '인스턴스 변수'를 의미하고 프로퍼티란 '필드와 접근자( Getter , Setter )의 조합'을 의미한다.

* 코틀린의 프로퍼티는 접근자에 의해 결정되며, 필드를 사용하지 않는다.

* 코틀린은 클래스의 접근자에서 자신의 프로퍼티에 접근하기 위해 'field' 키워드를 사용하고, 이것을 'Backing Field' 라고 한다.

* 코틀린의 클래스는 기본적으로는 상속이 닫혀 있고, 상속을 허용하려면 'open' 키워드를 사용해야 한다.

* 코틀린은 클래스를 위임하기 위해 'by' 키워드를 사용할 수 있다.

* 코틀린은 프로퍼티도 위임이 가능하며, 위임을 하기 위해서는 역시 'by' 키워드를 사용한다.

* 코틀린의 프로퍼티 위임은 Getter , Setter 연산자를 구현한 클래스로 위임하거나, 표준 라이브러리에서 제공하는 'lazy, observalbe, map' 등으로 위임할 수 있다.

* 코틀린은 자주 사용되는 '싱글턴(Singleton)' 패턴을 대체하는 'object' 클래스를 사용할 수 있다.

* 코틀린의 'Data' 클래스에서는 'toString , equals , hashCode' 메소드가 자동으로 구현된다.

* 코틀린의 클래스는 Java 와 가시성이 일부 다르다. 특히 코틀린은 package 변경자가 없고, 모듈 가시성인 'internal'을 지원한다.

* 코틀린은 클래스 내부에 클래스를 선언하는 경우 기본적으로 '중첩 클래스'가 된다. Java 와 같이 '내부 클래스'로 선언하려면 'inner' 키워드를 사용한다.

 

 

 

 

 

반응형

'IT > Android(비공개)' 카테고리의 다른 글

[Android] View / Theme  (0) 2020.03.05
Activity / Intent  (0) 2020.03.04
Android-studio / svn 연결  (0) 2020.03.04
4. Kotlin(코틀린)_3  (0) 2020.03.02
2. Kotlin(코틀린)_1  (0) 2020.02.20
1. Android 기본  (0) 2020.02.07
Android 재시작  (0) 2020.02.07