삽질의 현장/- .NET

#048_닷넷(.NET)_.Net Framework 기본 - ICloneable

shovelman 2015. 10. 30. 19:48


안녕하세요 삽잡이입니다.


지난 시간까지 열나게... 깊은 복사와 얕은 복사에 대해서 알아봤었지요...

이번 시간에는 복사가 가능하도록 기능을 제공해주는 

ICloneable 인터페이스에 대해서 알아보도록 하겠습니다.


ICloneable 인터페이스는 딱 하나의 인터페이스를 가지고 있습니다.

바로, object형을 반환해주는 clone()이라는 메서드를 가지고 있지요...

달랑 그거 하나입니다...


아무튼.. 왜 가지고 있을까요?



수 없이 많은 종류의 객체들 중에서 

복사에 대해 필요성을 가지고 있는 객체들은 몇개가 될까요?


class 외부에서 봤을 때..

즉, Client 입장에서 봤을 때 어떤 객체가 복사가 가능한지에 대해서 

그 유무를 파악할 수 있어야되지 않습니까?


따라서 복사할 수 있는 객체만 복사를 하도록, 아닌 객체들은 못하도록

만든 약속이 바로 ICloneable 인터페이스입니다.

한마디로, 약속이 지켜져있지 않는 객체들은 

즉, ICloneable 인터페이스를 구현하지 않은 객체들은 절대로 복사를 해서는 안됩니다.

왜냐하면 그 복사에 대한 보장을 해줄 수 없기 때문입니다.


객체의 내부를 우리가 알 수 있습니까?

클래스 내부가 다 감춰져 있는데 

내부에서 참조를 쓰는지 값을 쓰는지 어떻게 알 수 있습니까?

오직, 인터페이스의 약속만으로 우리는 판단할 수 있습니다.



이와 같이 구현을 통해 약속을 할 경우에

Rect 객체는 복사가 가능하다는 사실을 말하는 것입니다.


사실, Convariance 즉, 공변성에 의해 Rect Clone을 object로 사용합니다.



공변성이란,

'부모는 자식을 받아들일 수 있으나, 자식은 부모를 받아들일 수 없다는 원칙'입니다.

따라서, 자식을 받아들일 수 있는 모든 타입의 부모인 Object를 쓸 수 있다 이겁니다.


Rect의 부모 형식이 object이기 때문에

object를 반환한다는 것은 자식도 반환할 수 있다는 소리가 되기 때문입니다.


인자도 마찬가지입니다.

만약, 인자도 Rect, Point 이와 같은 형식으로 받는다고 하더라도,

똑같이 오버라이딩 할 수 있도록 object를 사용해도 됩니다.

Clone을 호출하는 곳에서 형식 변환만 해주면 되기 때문이지요...


object형식으로 반환을 한다면 형식 변한만 해주면 되는데...

그런데 인터페이스를 다룰 때에는 

인터페이스처럼 다루는 것이 좋다고 이전 시간에 말씀드린적이 있습니다.


그래서 일반적으로



이와 같은 방식으로 형식변환을 하고 사용합니다.

당연하게도 object형식을 반환하게 되면 자식 타입으로 형변환을 시켜주면 되겠지요.


이전 시간을 통들어 다시 한번 정리를 해볼까요!?


객체 내부에 참조를 가지고 있지 않다면, 얕은 복사가 가능합니다.

특히, 값 형식 객체 같은 것들은 복사하는 순간 그냥 단순히 복사가 되기 때문에,

참조만 되지 않다면 문제가 없습니다.




값 형식이 참조 형식을 가지고 있는 형태는 사실 사용하지 않는다고 생각해도 됩니다.

문법접적으로는 허용이 되지만, 권장은 하지 않습니다.

값을 표현하는 객체들이 당연히 값을 표현하겠지요.

하지만, 값 형식이 값 형식을 가지고 있는 형태는 사용이 됩니다.

뭐 이건, 얕은 복사이니까 그리 어렵지 않습니다.



참조 형식은 두 가지의 경우를 다 사용합니다.

참조 형식은 참조 형식, 값 혀식 둘 다 가질 일이 많이 있습니다.

참조 형식으로 부터 참조 형식을 가지고 있다면,

신경을 쓰시길 바랍니다. 깊은 복사가 필요하니깐 말입니다.


이번 시간은 여기까지 하도록 하겠습니다.


이상 삽잡이였습니다!