티스토리 뷰

kotlin

Generic

길 킴 2019. 10. 15. 19:28
728x90

1. 클래스에서의 사용

interface Generic<in T> {
   fun setItem(item: T)
}

class Sample : Generic<Generics type 정의> {
   override fun setItem(item: Generics type 정의) {
   	// 구현
   }
}   

2. 함수에서의 사용

private fun <T> abc(t: T) {
}

// Use
abc<String>("ABC")
abc("ABC")

 


Type 생략

1. 생략 가능한 경우

class Foo<out T>(val t: T)

@Test
fun test() {
   val foo1 = Foo<String>("foo1") // 생략 가능
   val foo2 = Foo("foo2") // 선언 가능
}   

2. 생략이 불가능한 경우

class Foo<T>

@Test
fun test() {
   val foo1 = Foo<String>() // 선언 가능
   val foo2 = Foo() // 선언 불가능!!
}   

 


Wildcard type argument in jAVA

  • 보통 잘 사용하지 않고, 라이브러리를 만들 때 유용하게 사용된다. 
  • 종류
    • - ? extends T : read만 가능한 서브타입 와일드 카드
    • - ? super T : write만 가능한 슈퍼 타입 와일드 카드 

- ? extends T

private void printAll(ArrayList<? extends Output<String>> items) {

  items.add(new Output<String() {  // => Error!
          @Override
          public boolean isArgument(String name) {
              return false;
              }
          });  
}

interface Output<T> {
	boolean isArgument(T name);
}

 

- ? super T

private void printAll(ArrayList<? super Output<String>> items) {
	for (int i = 0; i < items.size(); i++) {
    	if (items.get(i).isArgument("")) { // => Error!!
        }
    }
}

interface Output<T> {
	boolean isArgument(T name);
}

 

Kotlin의 in/out

- T : 별도의 Wildcard 정의가 없이 read/write 모두 가능

- in T : Java의 ? super T와 같고, input의 약자이며 write only

- out T : Java의 ? extends T와 같고, output의 약자이며 read only

private fun printAll(items: ArrayList<out Output<String>>) {
    items.indices
    	.filter { items[it].isArgument("") }
        .forEach { println("item : " + items[it]) }
}        

 

리턴 함수인 isArgument() 만 쓴다면, in T Generic Type을 줄 것을 권고한다.  (Warning Message 로 알려줌)

internal interface Output<in T> {
	fun isArgument(name: T): Boolean
}    

 


Star-Projections

private fun printArrayList(list: List<String>) {
	list.forEach {
    	println("it $it")
	 }	
}

private fun printArrayList(list: List<Intng>) {
	list.forEach {
    	println("it $it")
	 }	
}

@Test
fun test() {
    printArrayList(mutableListOf("AA", "BB", "CC"))
    printArrayList(mutableListOf(1, 2, 4, 5))
}

위의 코드를 아래로 간소화 할 수 있다. 

 private fun printArrayList(list: List<*>) {
    list.forEach {
    	println("it $it")
	}
}

@Test
fun test() {
    printArrayList(mutableListOf("AA", "BB", "CC"))
    printArrayList(mutableListOf(1, 2, 4, 5))
}

 

참고로, * 대신에 Any로도 된다. 

차이점은 * 는 필요한 만큼 함수를 만들고, Any는 Object 타입을 사용한 함수 하나를 만든다.  

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함