델리게이트와 메소드의 타입은 정확하게 일치해야 하는것이 원칙이다
그러나 상속관계에 있어서는 약간의 융통성이 있어 부모 자식 관계가 성립하면 타입이 일치하지 않더라고 호환성이 인정된다
부모 타입의 변수는 자식 객체를 가리킬 수 있다는 법칙이 델리게이트에도 그대로 적용되는 것

메소드의 리턴 타입이 델리게이트의 리턴 타입보다 더 자식 타입일 때 이 메소드를 델리게이트가 가리킬수 있다
이를 공변성이라 한다

리턴타입일때 (공변성)



-
dBase 타입의 db는 GetBase를 가리킬수 있는데 메소드와 델리게이트의 시그니처가 정확하게 일치한다
공변성에 의해 db에 GetDerived를 대입해도 잘 대입된다
자식은 부모의 일종이며 암시적으로 변환되기 때문이다
db 델리게이트로 호출된 결과는 Derived 객체인데 이 객체를 Base 타입의 변수로 대입받을 것이다
부모 타입의 변수가 자식 객체를 대입받았으므로 이 대입은 항상 안전하다

-
반대는 성립하지 않는다
dDerived타입의 dd는 시그니처가 일치하는 GetDerived를 가리킬수 있다
그러나 부모 타입을 리턴하는 GetBase는 가리킬수 없다
자식은 부모의 일종이지만 부모는 일종의 자식이 아니기 때문이다


인수타입일때 (반공변성)



-
dBase는 Base 타입을 인수로 취하는 델리게이트 타입이고
dDervied는 Derived 타입을 인수로 취하는 델리게이트 타입이다

dBase 타입의 변수 db에 GetBase를 대입하는 것은 당연히 가능하다
그러나 자식 타입을 취하는 GetDerived는 대입할수 없다
GetDerived의 본체에서는 인수로 받은 a객체를 Derived타입으로 인식하지만 호출하는 쪽에서는 Base타입의 객체를 넘기므로 변환되지않는다
자식 타입의 변수가 부모를 가리킬 수 없다

dDerived 타입의 변 dd에는 둘다 가느
GetBase를 dd에 대입가능한 이유는 dd로 호출할 때 Derived타입의 객체를 넘길수 있고
GetBase의 본체에서는 Base타입으로 받으므로 이 호출은 안전
부모 타입의 변수는 자식을 가리킬 수 있다
 
"부모는 자식을 가리킬 수 있다"
- 델리게이트를 통한 호출문에서 대입을 받는 쪽이 대입을 하는 쪽보다 더 상위 클래스이면 문제가 없다

ret = dele(형식 인수)
↑                ↑
더 부모타입이어야한다




- long과 int는 부모, 자식 관계는 아니지만 암시적으로 변환되는 관계
int 는 long에 손실없이 변환가능하므로 long이 더 부모타입

- dd =GetLong이 에러인것은 컴파일러가 부모자식관계로 인정하지 않기 때문
Posted by 코딩하는 야구쟁이
,