언제 그리고 왜 수업을 봉인 하시겠습니까?


87

C # 및 C ++ / CLI에서 키워드 sealed(또는 NotInheritableVB)는 상속 가능성으로부터 클래스를 보호하는 데 사용됩니다 (클래스는 상속 할 수 없음). 객체 지향 프로그래밍의 한 기능이 상속이라는 것을 알고 있으며이 기능을 사용하는 sealed것이 상속을 중단한다고 생각합니다. 이점 sealed과 사용이 중요한시기 를 보여주는 예가 있습니까?

답변:


96
  1. 보안 기능을 구현하는 클래스에서 원본 개체를 "가장"할 수 없습니다.

  2. 좀 더 일반적으로, 나는 최근에 마이크로 소프트의 한 사람과 교환을했는데, 그 사람은 치료하지 않고 방치하면 성능면에서 비용이 많이 들기 때문에 상속을 완전히 의미가있는 곳으로 제한하려한다고 말했습니다.
    봉인 된 키워드는 CLR에 메서드를 찾을 수있는 클래스가 더 이상 없음을 알려주며 속도를 높입니다.

요즘 시장에 나와있는 대부분의 성능 향상 도구에는 상속되지 않은 모든 클래스를 봉인하는 확인란이 있습니다.
그러나 MEF를 통해 플러그인 또는 어셈블리 검색을 허용하려는 경우 문제가 발생하므로주의하십시오.


3
재사용 된 라이브러리에서 클래스를 봉인하는 데주의해야합니다. 특히 타사에서 재사용 한 다음 MEF를 통해 코드베이스에 다시 통합하는 경우 특히 그렇습니다. 코드베이스는 주어진 클래스를 상속 할 수 없지만 제 3자는 상속합니다.
Louis Kottmann

10
1 번 이유는 모호하게 들리지만 대부분의 경우 "보안 기능"을 작성하지 않는다고 가정하면 이유 1이 거의 적용되지 않는다는 의미입니까? 이유 # 2는 성능 조정을위한 것입니다. 우리가 말하는 성능 차이는 얼마나됩니까? 비보안 클래스의 정의를 변경하는 것을 정당화 할만큼 충분히 중요합니까? 대답이 "예"라고하더라도 개발자가 코드 기반을 변경하도록하는 것보다 "밀봉되지 않은 모든 클래스에 대해 최적화 된 코드를 생성"하는 컴파일러 옵션이 이상적입니다.
RayLuo

1
처리하지 않고 방치하면 성능면에서 비용이 많이 듭니다. 미친 테스트 횟수보다 적은 수로 측정 할 수 있습니까?
t3chb0t

4
씰링이 엉망입니다. 테스트를 더 어렵게 만듭니다. FakeItEasy를 사용하여 몇 개의 ASP.NET 클래스를 조롱하고 싶지만 봉인 되었기 때문에 할 수 없습니다.
Warlike Chimpanzee

2
@RayLuo에 더 동의 할 수 없습니다. 사람들이 보안과 성능이 실제로 문제가되지 않는 클래스를 봉인하는 것을 여러 번 쳤습니다. 그들의 "봉인"은 단순히 클래스를 재정의해야하는 합리적인 필요성을 막았고 일을 훨씬 더 어렵게 만들었습니다. Warlike Chimpanzee가 말했듯이, 클래스를 조롱하는 것은 테스트에서 매우 일반적입니다.
ZZY

15

Baboon의 탁월한 답변에 대한 부록 :

  1. 클래스가 상속 용으로 설계 되지 않은 경우 하위 클래스가 클래스 불변을 깨뜨릴 수 있습니다 . 물론 이것은 퍼블릭 API를 생성하는 경우에만 실제로 적용되지만, 내가 경험하는 법칙에 따라 명시 적으로 서브 클래 싱하도록 설계되지 않은 모든 클래스를 봉인합니다.

관련 메모에서 봉인되지 않은 클래스에만 적용 할 수 있습니다. 생성 된 모든 메서드 virtual는 확장 점이거나 적어도 확장 점이어야하는 것처럼 보입니다. 방법 virtual을 선언 하는 것도 의식적인 결정이어야합니다. (C #에서는 의식적인 결정이지만 Java에서는 그렇지 않습니다.)


편집 : 일부 관련 링크 :

또한 Kotlin 은 기본적으로 클래스를 봉인합니다. open키워드는 자바의 반대 final또는 sealedC #의 . (확실히 이것이 좋은 일이라는 보편적 인 합의는 없습니다 .)


25
씰링 수업은 혜택보다 더 많은 두통을 유발합니다. 개발자가 클래스를 봉인하여 단순해야하는 일에 몇 시간이 걸리는 상황을 지속적으로 발견했습니다. 봉인 수업을 그만둬, 당신은 당신이 생각하는 것만 큼 재치 있지 않다. 꼭 필요한 경우에만 클래스를 봉인하십시오. 내가 편집 / 개봉 할 수없는 다른 사람의 봉인 된 수업을 처리해야하는 사람으로서 내 의견이다.
Gant Laborde

9
@GantMan의 코멘트는 본질적으로 "언제? 거의 없습니다. 왜? 이것이 당신이 그렇게하지 않는 이유입니다."라고 대답하기 때문에 실제로 OP의 질문에 대한 대답 중 하나로 간주되어야합니다. 별도의 답변으로 댓글을 다시 게시 한 다음 이에 대한 투표를 수집해야합니다. :-)
RayLuo

1
이 답변이 stackoverflow.com/a/7777674/3195477 참조 되었습니까? (단지) 사람의 이름을 지정하는 것보다 링크하는 것이 좋습니다
UuDdLrLrSs

2

수업을 다음으로 표시 Sealed 보안을 손상 시키거나 성능에 영향을 미칠 수있는 중요한 클래스의 변조 방지 할 수 있습니다.

여러 번, 클래스 봉인은 우리가 변경하고 싶지 않은 고정 된 동작을 가진 유틸리티 클래스를 디자인 할 때도 의미가 있습니다.

예를 들어 System네임 스페이스 in C#String. 봉인되지 않으면 기능을 확장 할 수 있으며, 이는 주어진 기능을 가진 기본 유형이므로 바람직하지 않을 수 있습니다.

마찬가지로 structuresin C#은 항상 암시 적으로 봉인됩니다. 따라서 하나의 구조 / 클래스를 다른 구조에서 파생시킬 수 없습니다. 그 이유는 우리가 수정하고 싶지 않은 독립형, 원자 적, 사용자 정의 데이터 유형만 structures을 모델링하는 데 사용되기 때문 입니다.

때로는 클래스 계층 구조를 구축 할 때 도메인 모델 또는 비즈니스 규칙에 따라 상속 체인의 특정 분기를 제한 할 수 있습니다.

예를 들어, a ManagerPartTimeEmployee모두 Employees이지만 조직의 파트 타임 직원 이후에는 역할이 없습니다. 이 경우 PartTimeEmployee추가 분기를 방지하기 위해 밀봉 할 수 있습니다 . 반면에 시간제 또는 주간 파트 타임 직원이있는 경우에서 상속하는 것이 합리적 일 수 있습니다 PartTimeEmployee.


String 클래스를 확장하는 것이 어떻게 바람직하지 않습니까? String은 여전히 ​​현재 작동하는 방식으로 정확하게 작동하며, 원하는 경우 추가 기능이있는 파생 클래스를 가질 수 있습니다. 그러면 어떤 문제에 대해 이야기하고 있습니까?
Kevin Wells

또한 상속 계층 구조를 "캡핑"하는 요점은 무엇입니까? 이는 계층을 확장해야한다면 먼저 부모 클래스의 봉인을 해제해야한다는 것을 의미합니다. 이는 비효율적입니다
Kevin Wells


1
그 대답조차 기본적으로 "왜 String을 파생시키고 싶습니까?"로 요약되고, String (예를 들어 null로 끝나는 문자열)을 파생하려는 이유를 언급하고 상속없이 처리해야한다고 말합니다. 그래서 왜 그것을 더 복잡하게 만들고 나중에 그것을 해결해야하는데 애초에 봉인되지 않은 상태로두고 옵션을 열어 둘 수 있습니다
Kevin Wells

두 번째 질문은 비즈니스 로직에 따라 원하지 않는 동작을 방지하는 것이 목표입니다. unseal나중에 클래스를 봉인하고 종속 된 모든 클래스를 깨뜨리는 것보다 필요한 경우 나중에 클래스 에 추가 하는 것이 더 쉽습니다 .
Akshay Khot

0

이 게시물에는 좋은 점이 있다고 생각합니다. 특별한 경우는 봉인되지 않은 클래스를 임의의 인터페이스로 캐스팅하려고 할 때 컴파일러에서 오류를 발생시키지 않습니다. 그러나 봉인을 사용하면 컴파일러에서 변환 할 수 없다는 오류가 발생합니다. 봉인 된 클래스는 추가적인 코드 액세스 보안을 제공합니다.
https://www.codeproject.com/Articles/239939/Csharp-Tweaks-Why-to-use-the-sealed-keyword-on-cla


1
솔루션에 대한 링크는 환영하지만 답변이없는 경우에도 유용한 지 확인하십시오 . 링크 주변에 컨텍스트를 추가 하여 동료 사용자가 그것이 무엇이고 왜 존재하는지 알 수 있도록 한 다음 페이지에서 가장 관련성이 높은 부분을 인용하십시오. 대상 페이지를 사용할 수없는 경우 다시 연결합니다. 링크에 불과한 답변은 삭제 될 수 있습니다.
Baum mit Augen

답변으로 게시 할 생각이 없어서 미안하지만 다른 답변과 관련이없는 것 같고 어디에 넣어야할지
모르겠습니다

1
제안에 따라 게시물을 편집했습니다. 원래는 다른 각도로 기여하고 싶지만 (아마도) 반대표 만 받았지만 아직 내용에 대해 이야기하지 않았습니다. -1이 그 이유를 친절하게 알려줄 수 있습니까?
strisunshine
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.