2011-10-15 28 views
51

Trong C# và C++/CLI, từ khóa sealed (hoặc NotInheritable trong VB) được sử dụng để bảo vệ lớp học khỏi bất kỳ cơ hội thừa kế nào (lớp học sẽ không thể kế thừa). Tôi biết rằng một tính năng của lập trình hướng đối tượng là thừa kế và tôi cảm thấy rằng việc sử dụng sealed đi ngược lại tính năng này, nó dừng kế thừa. Có ví dụ nào cho thấy lợi ích của sealed và khi điều quan trọng là sử dụng nó?Khi nào và tại sao bạn sẽ niêm phong một lớp học?

Trả lời

62

1) Trên một lớp thực hiện các tính năng bảo mật, sao cho đối tượng ban đầu không thể bị "mạo danh".

2) Nói chung, gần đây tôi đã trao đổi với một người ở Microsoft, người đã nói với tôi rằng họ đã cố gắng hạn chế quyền thừa kế ở những nơi mà nó thực sự có ý nghĩa, bởi vì nó trở nên hiệu quả cao nếu không được điều trị.
Từ khóa kín cho CLR biết rằng không có lớp nào tiếp tục xuống để tìm phương pháp, và điều đó tăng tốc mọi thứ.

Trong hầu hết các công cụ nâng cao hiệu suất trên thị trường hiện nay, bạn sẽ tìm thấy hộp kiểm sẽ đóng dấu tất cả các lớp của bạn không được kế thừa.
Hãy cẩn thận, vì nếu bạn muốn cho phép các plugin hoặc khám phá lắp ráp thông qua MEF, bạn sẽ gặp sự cố.

+0

lý do tại sao bạn gặp sự cố với MEF nếu sử dụng lớp được niêm phong? –

+3

Tôi có nghĩa là cẩn thận với niêm phong các lớp học trong các thư viện tái sử dụng, đặc biệt là nếu chúng được tái sử dụng bởi các bên thứ ba và sau đó tái hòa nhập (thông qua MEF) vào codebase. Codebase của bạn có thể không kế thừa một lớp nhất định mà bên thứ ba sẽ. –

+0

Lý do # 1 nghe có vẻ mơ hồ nhưng, giả sử chúng ta không viết "tính năng bảo mật" phần lớn thời gian, điều đó có nghĩa là lý do # 1 hầu như không áp dụng? Lý do # 2 là để điều chỉnh hiệu suất.Chúng ta đang nói về sự khác biệt về hiệu suất bao nhiêu? Chúng có đủ quan trọng để biện minh cho việc thay đổi định nghĩa của lớp không bảo mật không? Ngay cả khi câu trả lời là "có", điều này lý tưởng là tùy chọn trình biên dịch tức là "tạo mã được tối ưu hóa cho tất cả các lớp không được niêm phong", thay vì yêu cầu các nhà phát triển thay đổi cơ sở mã. – RayLuo

7

Một phụ lục câu trả lời tuyệt vời Baboon của:

3) Nếu một lớp không là thiết kế cho thừa kế, lớp con có thể phá vỡ class invariants. Điều này thực sự chỉ áp dụng nếu bạn đang tạo một API công khai, tất nhiên, nhưng khi tôi quy tắc ngón tay cái, tôi niêm phong bất kỳ lớp nào không được thiết kế rõ ràng để được phân lớp.

Trên ghi chú liên quan, chỉ áp dụng cho các lớp chưa được niêm phong: bất kỳ phương thức nào được tạo virtual là một điểm mở rộng hoặc ít nhất có vẻ là điểm mở rộng. Phương pháp khai báo virtual cũng phải là một quyết định có ý thức. (Trong C# đây là một quyết định có ý thức; trong Java nó không phải là.)


EDIT: Một số liên kết có liên quan:

Cũng lưu ý rằng Kotlin con dấu các lớp học theo mặc định; its open keyword is the opposite of Java's final or the sealed of C#. (Để chắc chắn, there is no universal agreement that this is a good thing.)

+8

Lớp niêm phong gây đau đầu nhiều hơn lợi ích. Tôi đã liên tục tìm thấy các tình huống mà các nhà phát triển đã niêm phong các lớp học, khiến tôi gặp khó khăn trong những gì nên đơn giản. Dừng các lớp học niêm phong, bạn không hóm hỉnh như bạn nghĩ. Chỉ đóng dấu các lớp học nếu bạn PHẢI, và thậm chí sau đó, xem xét lại. Chỉ là ý kiến ​​của tôi, là người phải đối phó với các lớp học kín của người khác mà tôi không thể chỉnh sửa/bỏ niêm phong. – GantMan

+2

@GantMan 's bình luận thực sự nên được coi là một trong những câu trả lời cho câu hỏi của OP, bởi vì nó về cơ bản đưa ra một câu trả lời là "Khi nào? Hardly. Tại sao? Đây là lý do tại sao bạn không làm điều đó." Cấp cho bạn nên đăng lại nhận xét của bạn dưới dạng câu trả lời riêng và sau đó thu thập phiếu bầu cho nhận xét đó. :-) – RayLuo

-1

Tôi nghĩ rằng bài đăng này có một số điểm tốt, trường hợp cụ thể là khi cố gắng để đúc một lớp không niêm phong đến bất kỳ giao diện ngẫu nhiên, trình biên dịch không ném lỗi; nhưng khi niêm phong được sử dụng trình biên dịch ném lỗi mà nó không thể chuyển đổi. Lớp niêm phong mang lại bảo mật truy cập mã bổ sung.
https://www.codeproject.com/Articles/239939/Csharp-Tweaks-Why-to-use-the-sealed-keyword-on-cla

+1

Liên kết đến giải pháp được chào đón, nhưng hãy đảm bảo câu trả lời của bạn hữu ích khi không có: [thêm ngữ cảnh xung quanh liên kết] (// meta.stackexchange.com/a/8259) để người dùng đồng nghiệp của bạn sẽ có một số ý tưởng nó là gì và tại sao nó ở đó, sau đó trích dẫn phần có liên quan nhất của trang bạn đang liên kết đến trong trường hợp trang đích không có sẵn. [Câu trả lời có nhiều hơn một liên kết có thể bị xóa.] (// stackoverflow.com/help/deleted-answers) –

+0

Xin lỗi tôi không có ý định đăng câu trả lời, nhưng có vẻ như không liên quan đến các câu trả lời khác và tôi không biết đặt nó ở đâu – strisunshine

+0

Tôi đã chỉnh sửa bài đăng theo đề xuất. Ban đầu tôi chỉ muốn đóng góp một góc độ khác nhau (có lẽ), nhưng tôi chỉ có một downvote và chúng tôi đã không nói về nội dung được nêu ra, có thể -1 vui lòng cho biết lý do? – strisunshine

Các vấn đề liên quan