삽질의 현장/- .NET

#035_닷넷(.NET)_.Net Framework 기본 -Object 메서드 (virtual)

shovelman 2015. 10. 28. 08:46


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


모든 타입의 부모는 Object Class이지요...

그런데 이 Object에는 메서드들을 제공해줍니다.


다음은 object 클래스에서 제공해주는 메서드들입니다.



이와 같은 메서드들은 크게 '가상 멤버 메서드', '인스턴스 멤버 메서드', '정적 멤버 메서드'로

이루어져 있습니다.


'가상 메서드' 및 '인스턴스 메서드'로 이루어진 것들은 추후 자식 클래스에서 재정의 할 수 있게 되고,

'정적 메서드'로 이루어진 것들은 클래스 수준에서 호출할 수 있게 됩니다.


하나하나 살펴보도록 하겠습니다.

object 클래스에서 'Equals', 'GetHashCode' 메서드들은 항상 같이 묶여 다닙니다.

즉, 오버라이드가 되어야 한다면 둘 다, 둘 중 하나 할 것이면 둘 다 하지 않는게 바람직합니다.


Hash는 '해쉬 코드'라고 많이들 들어보셨을 터인데...

키에 해당하는 address를 알면 value를 바로 찾아올 수 있는 자료구조에 포함됩니다.

우선, 해시란, '키 값에 따른 Value 값을 상수 값으로 접근 가능하도록 하는 값'을 의미합니다.

제가 너무 어렵게 설명하는 것 같습니다...


자... 쉽게(?) 가봅시다... (그런데 지금은 해시에 대해서 알아보는 시간이 아닙니다.)



이 Hash Function()의 인자로 Key가 들어가게 되면 return 시 address가 반환되는 구조입니다.

주소를 알게되면 Hash Table로 부터 value를 찾아옵니다.

따라서 address 값을 알게 되면 저장한 값을 찾아올 수 있게 됩니다.


모든 객체가 address의 키로 사용될 수 있습니다.

정수 객체만 되는 것이 아니라, 모든 형식의 객체가 해시의 키로 사용될 수 있다 이겁니다.

단, 키를 사용하면서 주소를 얻을 수 있어야합니다.


Java, C#, .NET에서는 

모든 객체에 GetHashCode()라는 메서드를 만들었습니다.

따라서, GetHashCode()를 가지고 있는 객체는 해시 코드를 가지고 있다는 말이 되고,

이 메서드를 통해 무작위 유니코드를 반환하게 됩니다.

해당 메서드는 무작위한 정수값을 반환하게 되는데

뭐... 해시코드가 겹칠일은 거의 없겠지만, 유일성을 보장하지는 않습니다...


만들어놓은 객체를 해시 테이블의 키 값으로 사용될 수 도 있을 것이고,

주소를 가공하기 위한 정보를 필요로 할 때가 있을 수도 있습니다.

왜냐하면, 우리가 만든 객체가 언제 어떻게 사용될지는 모르기 때문입니다.

따라서, 해시코드를 구현 시 굉장히 복잡해 질 수도 있으니

내부적으로 GetHashCode() 라는 메서드를 제공해줘서

정수값을 만들어 주소를 구할 수 있다 이 말입니다.


자료구조과목에서 해시코드를 구현해보신분들이라면 아시겠지만,

주소를 얻기 위해서 문자열 더하고 아스키 코드 추출하고 합 구하고 별의 별 Show를 다 했는데,

이런 시간을 아껴서 제공해준 기능이 GetHashCode()라는 것이지요....

왜냐하면, 해당 메서드는 키값의 랜덤하고 유니크한 정수 값을 얻고,

이를 통해 주소를 가공할 수 있으니 말입니다.



다음으로 equals() 메서드를 알아보도록 하겠습니다.

이 equals() 메서드는 객체를 비교할 수 있는 메서드입니다.

즉, this (자기 참조)와 상대방 객체를 비교하게 되는 것입니다.


그런데, 잘 생각해보시길 바랍니다.

객체가 같냐고 묻는 것은 해시 코드도 같아야 된다는 소리입니다.

그래야 만약, 해시의 키 값으로 사용될 때 같은 해시 코드를 사용할 것이고,

주소도 같고, 객체가 같다는 증명이 되지 않겠습니까?


따라서 무조건 equals() 메서드를 오버라이드하는 경우에는

GetHashCode() 메서드도 오버라이드 해줘야합니다.


그런데 잘 보시면 equals() 메서드는 가상 메서드입니다.

따라서 기본적으로 참조를 비교하는데, 

일반적으로 비교 대상 객체의 내부 상태값을 비교하도록 재정의합니다.


즉, equals() 메서드의 기본은 '참조 비교'입니다.


아래의 예제를 살펴보시길 바랍니다.



해당 예제 코드의 메모리 구조를 살펴보도록 하겠습니다.



만약, equals() 메서드를 오버라이드 하지 않았을 경우에는 참조를 비교하게 됩니다.

즉, 객체가 다르기 때문에 false를 반환하게 되지요...



하지만, equals() 메서드는 일반적으로 값 비교를 위해 재정의하기 때문에

override를 통해 재정의하면 값을 비교해 true가 반환되도록 할 수 있습니다.


다시한번 강조하지만,

equals() 메서드의 기본은 '참조 비교'입니다.

하지만, 일반적으로 '값 비교'를 위해 오버라이드를 할 수 있다 이겁니다.


기본적으로 객체의 비교는 세 개로 나뉠 수 있습니다.

virtual equals(), static equals(), static reference equals() 이렇게 말입니다...


static equals() 들은 다음 시간에 살펴보도록 하겠습니다.


그리고 혹여나 말씀을 드리자면...

ToString() 메서드는 이전에 줄곧 언급 드렸기에 생략하겠으며

Fianlize() 메서드의 경우에는 다음 시간에 알아보도록하지요...

뭐 간단하게 말하자면,

fianalize() 메서드를 오버라이드하게되면, 객체의 마무리 작업을 할 수 있게됩니다.

그리고 소멸자가 없는 언어를 위해 finalize() 메서드를 제공해주는 것이지요...



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

많이 알아봤군요...


이상 삽잡이였습니다!




<참고 : C# and the .NET4 Platform>