일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 파이썬
- 스칼라
- Adapter 패턴
- Golang
- 이더리움
- 주키퍼
- 스위프트
- play 강좌
- Play2 로 웹 개발
- Play2
- 안드로이드 웹뷰
- 파이썬 동시성
- 파이썬 강좌
- 엔터프라이즈 블록체인
- hyperledger fabric
- Actor
- 스칼라 강좌
- 하이퍼레저 패브릭
- 블록체인
- 플레이프레임워크
- Akka
- Hyperledger fabric gossip protocol
- CORDA
- 파이썬 머신러닝
- 스칼라 동시성
- play2 강좌
- akka 강좌
- 하이브리드앱
- 그라파나
- 파이썬 데이터분석
- Today
- Total
HAMA 블로그
스칼라 강좌 (10) - 공변성,불변성,역공변성 본문
공변성,불변성,역공변성
백그라운드
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
스칼라로 설명
'Scala' 카테고리의 다른 글
스칼라 강좌 (12) - 객체의 동일성 (0) | 2016.07.08 |
---|---|
스칼라 강좌 (11) - while 루프 와 재귀 (0) | 2016.07.03 |
스칼라 강좌 (9) - Stack / Queue (0) | 2016.06.26 |
스칼라 강좌 (8) - ArrayBuffer 와 Vector 그리고 공변성 (0) | 2016.06.26 |
스칼라 강좌 (7) - 컬렉션과 자바 (0) | 2016.06.26 |