본문 바로가기
  • hazard_dev@__
  • hazard_dev@__
Kotlin

[Kotlin#8] Kotlin(코틀린) Generics 및 Delegation Pattern In Class[1]

by Hazard3_o00sung 2020. 12. 24.
728x90

안드로이드를 대표하는 언어 코틀린입니다!

Powerful Functional and OOP in Kotlin

  저번 글에서는 데이터 클래스와 봉인 클래스에 대해서 알아보았습니다!! 만약 보지 못하신 분이라면 아래 링크를 타고 들어가셔서 보시고 오시는 것을 추천드립니다!!

hazarddev.tistory.com/58

 

[Kotlin#7] Kotlin(코틀린) 데이터 클래스 및 봉인 클래스(Data Class & Sealed Class)

Powerful Functional and OOP in Kotlin 저번 시간에는 코틀린의 클래스 내부에서 선언되는 접근 한정자에 대해서 알아보았습니다. 이번 시간에는 코틀린에서의 데이터 클래스와 봉인 클래스(Sealed Class)에

hazarddev.tistory.com

이번에는 Generics라고 하는 개념에 대해서 알아보도록 할 예정입니다. 물론 위임 패턴 또한 간단하게 알아보도록 하겠습니다.  우선 제네릭을 기반으로 해서 설명을 드리자면, 자바와 매우 유사하지만 코틀린에서의 제네릭 개념은 좀 더 읽기 쉽고, 쉽게 만드는 것을 도와줍니다. 당연히 이렇게 설명을 드리면 무슨 내용인지 이해를 하기 힘듭니다. 그래서 코틀린은 키워드 두 개를 추가해서 이를 돕고자 합니다! 바로 out과 in개념을 활용해서 학습하는 것입니다. 

 

코틀린에서 클래스와 객체 유형은 상이한 측면이 존재합니다. 아래 예제를 통해서 알아보도록 합시다!!

 

1
2
3
4
5
6
fun main(){
    val foo:Int = 20
    val bar:Number = foo
 
    print(bar)
}
cs

 

위의 코드를 순서대로 읽어보도록 하겠습니다. 우선 foo라는 Int형 변수를 하나 선언하고 숫자를 할당해 초기화 해주었습니다! 그리고 foo라는 변수는 bar라는 변수에 대입이 다시 되었다는 것을 알 수 있습니다. 하지만 두 개의 변수는 유형이 다르죠? 하나는 Int타입이고, 다른 하나는 Number타입이기 때문에 타입이 다르다는 것을 알 수 있습니다. 하지만 대입하는데 문제가 없고 출력하는데도 문제가 발생하지 않았습니다. 이유로는 Int가 Numbe 클래스의 하위 클래스로 서브타입이기 때문에 가능한 것입니다. 그렇기 때문에 동적 바인딩을 통해 타입 할당에 아무런 문제가 발생하지 않은 거죠,

 

이해가 되셨다면 좀 더 깊이 넘어가 보겠습니다. 만약 하나의 애플리케이션에서 사용되는 데이터의 타입이 확실하지 않은 경우가 많이 존재합니다. 예를 들면 한 클래스가 존재할 때, 클래스 내부에 있는 변수가 어떨 때는 String, Int 이런 식으로 동적으로 바뀌는 상황이 존재한다는 말이죠, 이런 문제를 해결하기 위해 코틀린에서의 제네릭은 <T>로 정의되며, T는 템플릿을 의미합니다. 그렇게 코드를 작성하게 되면 컴파일러 레벨에서 동적 바인딩을 통해 유연한 코드 작성을 가능케 하는 것입니다. C++을 학습하신 분이라면 아실지도 모르겠으나, C++의 템플릿을 상상하시면 이해가 쉬울 것 같아 C++ 코드도 같이 기입을 할 테니 코드를 확인해보시기 바랍니다!!

 

/* C++ Code */

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
#include <string>
 
template<typename T> class Foo{
    public:
        T val;
        T val2;
 
        Foo(T c, T d):val(c),val2(d){}
 
        void show() const {
            std::cout << this->val << " " << this->val2 << std::endl;
        }
};
 
int main()
{
    Foo<int> *foo = new Foo<int>(1224);
    Foo<const char *> *foo2 = new Foo<const char *>("name" , "Gildong");
 
    foo->show();
    foo2->show();
    return 0;
}
cs

 

/* Kotiln Code */

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Foo<T>(val obj:T){
    init{
        println("Hello  :" + obj);
    }
 
    val obje:T = obj
    fun show() {println(obje)}
}
 
fun main(arg:Array<String>)
{
    var foo = Foo<String>("Gildong")
    var bar = Foo<Int>(10)
}
 
cs

 

C++의 코드는 몰라도 됩니다. 제가 원래 블로그에서 어떤 프로그래밍 언어 간 비슷한 개념이 있을 때 아시는 분이 있으시면 이해하는데 좀 더 도움이 되시라고 올리는 거니까요~ 우선 제 의견을 말씀드리기 전에 저는 C/C++를 정말 너무 사랑하지만 코틀린의 제네릭 개념은 다른 언어에서 보다 훨씬 유연하게 사용되는 것 같습니다. 물론 동적 언어는 제외하지만요! 코드를 보게 되면 <T>로 표시되는 부분이 존재합니다. 이 부분이 바로 제네릭 개념이 이입되는 부분이라고 볼 수 있습니다. 제네릭 유형을 하위 멤버 변수나 함수에 적용하기 위해서는 그냥 간단하게 T라고만 타입 선언을 해주면 그만입니다. 얼마나 간단한가요

 

 

이제 Delegation Pattern을 설명드려야 하는데 내용이 방대하기도 하며, 패턴에 대해서 아시는 분이라면 안 보셔도 상관없겠지만, 물론 다시 보셔도 좋고... 다음 글에서 올리도록 하겠습니다!

 

글 잘 읽으셨다면 공감 하트 한 번씩 눌러주시면 감사하겠습니다🤗🤗🤗🤗🤗

 

 

댓글로 문의, 피드백, 질문 모두 받으니까요 편하게 달아주세요!!

 

감사합니다!😍😍😍😍😍😍😍

728x90

댓글