관리 메뉴

HAMA 블로그

스칼라 강좌 (10) - 공변성,불변성,역공변성 본문

Scala

스칼라 강좌 (10) - 공변성,불변성,역공변성

[하마] 이승현 (wowlsh93@gmail.com) 2016. 6. 27. 21:07

공변성,불변성,역공변성

 
자바로 설명

 

백그라운드

Object <- Number <- Integer or Double  같이 차례로 상속받는 타입이 있다고 가정할때 

Object <- Animal <- Cat or Dog 도 괜찮습니다.

공변성  (covarience, out, producer : 즉 get만 가능)
List<? extends Number>  란 Number 를 상속받는 타입으로 이루어진 리스트란 말이구요.
즉 List<? extends Number> 로 선언되어 있다면  List<Integer> 이나 List<Double> 를 사용할 수 있다라는 말로 공변성(covariance) 지원한다라고 하구요. (자식 타입으로 치환가능)

역공변성(contravarience, in, consumer : 즉 add, put, set 가능 get 불가 ) 
List<? super Number> 란 Number 의 부모타입으로 이루어진 리스트란 말입니다. 
즉 List<? super Number> 로 선언되어있다면 List<Object> 를 사용 할 수 있다라는 말로
역공변성(Contravarience) 지원한다라고 합니다. (부모 타입으로 치환 가능) 

불변성

둘다 지원안하면 불변성(invarience) 입니다. (타입전환 불가) 

예제로 이해하자

자 다음 예제를 보시죠.

public static void copy(List<? extends Number> source, List<? super Number> destiny) {   
	for(Number number : source) {     
    		destiny.add(number);   
    } 
}  

* source 로는 Number 를 상속한 타입의 리스트를 받을 수 있다. (Covariance 가능하다)  
* destiny 로는 Number 의 부모타입의 리스트를 받을 수 있다. (Contravarience 가능하다)    

List<Integer> myInts = Arrays.asList(1,2,3,4);  // Integer 의 리스트  
List<Double> myDoubles = Arrays.asList(3.14, 6.28); // Double 의 리스트 
List<Object> myObjs = new ArrayList<Object>();  // Object 리스트  
copy(myInts, myObjs);   // Integer 의 리스트에서 get 해서 Object 의 리스트로 put 하라  
copy(myDoubles, myObjs);// Double 의 리스트에서 get 해서 Object 의 리스트로 put 하라   

결과: myObjs ->  [1, 2, 3, 4, 3.14, 6.28]

 

보통  Covariance 을 허락 하는곳은 get 이며 , Contravarience 는 put 입니다. 

 

 

PUT / ADD

put 이란 값을 넣는다는건데 ,부모가 자식들의 형태를 모두 취하는건 일리가 있지만 

같은 부모의 A 자식이 B 자식을 취하는건 좀 넌센스죠. (개가 고양이를 취함, Integer 가 Double 을 취함)

 

* 사실 put,add 처럼 먼가 변경하는것은 invariance, immutable이 아니면  위험요소가 항상 있다. 그래서 순수함수형언어에서는 covariance 성질을 가져도 ㅇㅋ 지만 , 스칼라나 자바에서는 주의를 해야한다. 

* 다음 예를 보면 제너릭이 아닌 일반 배열에서도 covariance 는 위험하다는걸 보여준다.

void put(Object[] list) {    list[0]=10;}

put(new String[1]);


GET 

 get 은 값을 꺼내는건데, 자식들의 값을 꺼내는건 일리가 있지만 , 어떤 타입이 들어 있을지 모를 부모의 리스트에서 값을 꺼내어 사용한다는것은 안개속을 시속 300km 로 달리는 위험한 것 이다.

 

 

 

코틀린으로 설명 


개인적으로 이 설명이 가장 쉽게 써져 있는거 같습니다. (초반엔 자바로도 설명함)

https://kotlinlang.org/docs/generics.html 

 

 


스칼라로 설명

 

https://twitter.github.io/scala_school/ko/type-basics.html

Comments