라는 궁금증을 꽤 오래전부터 가지고 있었습니다.
아시다시피, Java 클래스의 멤버는 기본적으로 virtual 합니다.
즉, 클래스 작성자의 의도와 상관없이, 다른 사람이 파생을 통해 임의로 구현을 달리할 수 있습니다.
다형성의 결정권이 파생 클래스에게 있는 것이죠.
그런데, C#에서는 클래스 작성자가 virtual 로 한정하지 한 파생 클래스 작성자가 임의로 구현을 달리할 수는 없습니다. 즉, 다형성의 결정권이 기반 클래스에게 있다고 할 수 있습니다.
C#은 자바를 모티브로 만들어졌지만, 다형성 실현 방식에 관해서는 자바와 반대되는 입장을 취하고 있는 것이죠.
방식이 다르다는 점은 알겠는데, "도대체 어떤 이득이 있길래"라는 해소되지 않은 궁금증이 있었습니다. 그런데, 최근에 조금이나마 그 이득을 짐작하게 되었습니다.
class Old
{
public string Price => "10,000 원";
}
// 다형성을 파생이 결정한다면,
class New : Old
{
public override string Price => "10,000 원입니다.";
}
New 가 나오기 전 Old의 클라이언트들은 아래와 같이 사용했을 수도 있습니다.
string priceText = old.Price + "입니다."
Old.Price는 “10,000 원” 까지만 출력한다는 기대를 바탕으로 클라이언트 코드가 작성된 것이죠.
그런데, 다형성이 발동한 경우, 이 기대에 배신을 당합니다.
// "10,000 원입니다.입니다."
.
C#이 처음 소개되었을 시기에는, Java 를 통해 객체 지향의 개념이 이제 막 퍼지기 시작했을 시기였을 것입니다.
클래스 사용자는 클래스의 정의를 믿고, 파생자는 다형성 장치를 수시로 사용했겠죠.
그런데, 부분적으로는 참인 위 두 개의 명제가 합쳐지면 거짓이 되는 역설적인 상황을 Java 사용자들은 심심치 않게 마주쳤을 것으로 추측이 됩니다.
C#은 이러한 역설을 방지하기 위해, 클래스 사용자에게 다형성으로 인한 변동 가능성을 미리 고지하는 방식을 선택한 것은 아닌가 하는 짐작을 했습니다.
제품의 사용 설명서에서 가끔 보이는 "변경 고지문"과 같은 역할을 할 수 있도록 말이죠.
“색상, 디자인 등은 제품의 성능 향상을 위해 예고 없이 변경될 수 있습니다”
.
이 장치로 인해, 클래스 사용자는 class의 멤버 중 무한 신뢰해도 되는 것들과,
string GetString() ...
마냥 신뢰할 수 만은 없는 것들을 구분할 수 있게 된 것이죠.
virtual string GetString()