C#은 자바의 장점을 수용하고, 자바가 모델로 삼은 C++의 장점도 일부 수용하였기에 C#은 자바보다 표현 능력은 약간 낫다고 할 수 있다. C#에는 있지만 자바에는 없는 기능으로는 C++의 function pointer의 객체 버전이라 할 수 있는 delegate, 멤버 변수이외에 별도의 Property 둔 것, delegate 기반의 Event, indexer 등을 들 수 있다. C#의 Interface는 자바의 Interface와 달리 위에서 언급한 property, event, indexer 등을 선언할 수 있다. 또한 이글에서 말하고자하는 아주 작지만 재밌는 차이도 있다. 예전에 유익하게 읽었던 Effective Java 기억에 Effective C#을 읽다가 의심이 나서 테스트를 하게 되었다. // C# interface IMsg { void Message(); } class Parent : IMsg { public void Message() { Console.WriteLine("부모가 불렸네."); } } class Child : Parent { public new void Message() { Console.WriteLine("자식이 불렸네."); } } // Java public interface IMsg { void Message(); } public class Parent implements IMsg { public void Message() { System.out.println("부모가 불렸네."); } } public class Child extends Parent { public void Message() { System.out.println("자식이 불렸네."); } } 두 언어 중 하나만 아는 사람이 봐도 위 코드는 같게 구현되어 있음을 알 수 있다. 이 경우 아래와 같은 코드에 의해 찍히는 값은 어떻게 될까 ? IMsg message = new Child(); message.Message(); C#의 경우는 "부모가 불렸네", Java의 경우 "자식이 불렸네." 이다. Effective C# (빌와그너 저, 김명신 역)는 이렇게 적고 있다. C#에서 Inferface의 구현은 virtual 메소드의 overriding과는 전혀 다른 것이며, Interface는 그것을 구현한 클래스를 바라보는 제한된 창이며 계약이다. Java와 같은 결과를 얻으려면 어떻게 할까 ? 우선, Child 클래스의 선언시 Interface를 구현하는 것으로 지정한다. 즉, class Child : Parent, IMsg 자바와 마찬가지로 C#도 클래스의 단일 상속, 인터페이스의 복수 상속을 규정하고 있다. 혹은 다음과 같은 Parent 클래스의 IMsg 구현시 메소드를 virtual로 선언하고 Child에서 override하면 된다. class Parent : IMsg { public virtual void Message() { class Child : Parent { public override void Message() { 이 테스트에서 추론할 수 있는 것은 자바의 경우 Interface의 구현과, 상속을 통한 polymorphism이 동일하게 동작하는 듯 하며, C#은 이를 분명히 구분하고 있다.