추상 클래스에서 상속되는 클래스를 만들 때 상속 된 추상 클래스를 구현할 때 override 키워드를 사용해야하는 이유는 무엇입니까?
"왜?" 이와 같은 질문은 모호하기 때문에 대답하기 어려울 수 있습니다. 귀하의 질문은 " override키워드가 필요한 위치를 주장하기 위해 언어 디자인 중에 어떤 주장을 할 수 있습니까?" 라고 가정하겠습니다.
한 발 물러서서 시작합시다. Java와 같은 일부 언어에서는 메소드가 기본적으로 가상이며 자동으로 대체됩니다. C #의 디자이너는 이것을 알고 Java의 사소한 결함이라고 생각했습니다. C #은 "어리석은 부분이 제거 된 Java" 가 아니라 C # 의 디자이너는 C, C ++ 및 Java의 문제가있는 디자인 포인트에서 배우고 C #에서 복제하지 않기를 원했습니다.
C # 디자이너는 재정의를 가능한 버그의 원인으로 간주했습니다. 결국, 그것은 테스트 된 기존 코드의 동작 을 변경 하는 방법 이며 위험합니다. 재정의는 우연히 또는 우연히 수행되어야하는 것이 아닙니다. 그것에 대해 열심히 생각하는 누군가 가 설계 해야 합니다 . 그렇기 때문에 기본적으로 메서드가 가상이 아니며 메서드를 재정의한다고 말해야하는 이유가 있습니다.
이것이 기본적인 추론입니다. 이제 좀 더 진보 된 추론을 할 수 있습니다.
StriplingWarrior의 답변은 좀 더 진보 된 논쟁을 할 수있는 첫 걸음입니다. 파생 클래스의 작성자에게 기본 클래스에 대한 정보가없고 새로운 메서드를 만들려고 할 수 있으며 사용자가 실수로 재정의하도록 허용해서는 안됩니다 .
이 시점이 합리적이지만 다음과 같은 여러 가지 반론이 있습니다.
- 파생 클래스의 저자 는 기본 클래스에 대한 모든 것을 알아야 할 책임이 있습니다 ! 그들은 그 코드를 재사용하고 있으며, 코드를 재사용하기 전에 철저히 이해하기 위해 실사를해야합니다.
- 특정 시나리오에서 가상 방법은 추상적입니다. 재정의 하지 않으면 오류가 발생 하므로 작성자가 실수로 구현을 작성하지 않았을 가능성이 큽니다.
그런 다음이 시점에서 더욱 발전된 주장을하자. 어떤 상황에서 파생 클래스의 작성자가 기본 클래스의 역할을 알지 못해서 면제 될 수 있습니까? 다음 시나리오를 고려하십시오.
- 기본 클래스 작성자는 추상 기본 클래스 B를 만듭니다.
- 다른 팀의 파생 클래스 작성자는 메서드 M을 사용하여 파생 클래스 D를 만듭니다.
- 기본 클래스 작성자는 기본 클래스 B를 확장하는 팀이 항상 메소드 M을 제공해야하므로 기본 클래스 작성자는 추상 메소드 M을 추가합니다.
- 클래스 D를 다시 컴파일하면 어떻게됩니까?
우리가 일어나고 싶은 것은 D의 저자에게 뭔가 관련이 바뀌 었다는 정보가 있다는 것 입니다. 변경된 관련 사항은 M이 이제 요구 사항이며 해당 구현에 과부하가 발생해야한다는 것입니다. 기본 클래스에서 호출 될 수 있음을 알고 있으면 DM의 동작을 변경해야 할 수도 있습니다. 올바른 것은 "오, DM이 존재하고 BM을 확장합니다"라고 말하지 않는 것 입니다. 컴파일러가 올바른 일을하는 것은 실패 하고 "D의 저자 인 Hey는 더 이상 유효하지 않은이 가정을 확인하고 필요한 경우 코드를 수정하십시오"라고 말합니다.
당신의 예에서,이 가정 override이었다 옵션 에 SayHello가 추상 메소드를 오버라이드 때문이다. 두 가지 가능성이 있습니다. (1) 코드 작성자가 추상 메서드를 재정의하려고하거나 (2) 다른 사람이 기본 클래스를 변경했기 때문에 재정의 메서드가 우연히 재정의 되고 코드가 미묘한 방식으로 잘못되었습니다. 선택 사항 이라면 이러한 가능성을 구별 할 수 없습니다override .
하지만 override되어 필요한 우리는 떨어져 세 가지 시나리오를 알 수 있습니다. 가능한 실수가 코드가있는 경우 다음 override됩니다 실종 . 그것은 의도적으로 무시되는 경우 override이다 존재 . 그리고 의도적으로하면 되지 다음 오버라이드 (override)하는 new것입니다 존재 . C #의 디자인을 통해 이러한 미묘한 차이를 만들 수 있습니다.
기억 보고는 개발자의 마음을 읽는 필요 컴파일러 오류 ; 컴파일러는 잘못된 코드 에서 작성자가 생각한 올바른 코드를 추론 하고 올바른 방향으로 오류를 표시해야합니다. 개발자가 생각한 것에 대한 코드를 남길 수있는 단서가 많을수록 컴파일러가 오류보고에서 더 잘 수행 할 수 있으므로 버그를 더 빨리 찾고 수정할 수 있습니다.
그러나 더 일반적으로 C #은 코드가 변경되는 세상을 위해 설계되었습니다 . "이상한"표시의 C #의 수많은 기능이 있다고 가정 할 때, 사실 그들은 개발자가 알려 때문이다 유효한 것으로 사용이 기본 클래스가 변경 되었기 때문에 무효가되었다. 이 버그 클래스를 "취약한 기본 클래스 실패"라고하며 C #에는이 실패 클래스에 대한 여러 가지 흥미로운 완화 방법이 있습니다.