Nếu tôi triển khai Giao diện, nó có được gọi là Kế thừa không?


31

Nếu lớp tôi implementscó giao diện thì tôi có thể nói rằng tôi đang theo thừa kế không? Tôi biết rằng khi một lớp extendskhác lớp thì đó là sự kế thừa.


Có thể trùng lặp khả năng kế thừa giao diện trong ngôn ngữ tự nhiên
gnat

7
Nhận xét của Jodrell đơn giản là sai. Việc thực hiện một giao diện thực sự là sự kế thừa và kế thừa một giao diện từ một giao diện khác là sự kế thừa. Làm sao mà chúng ta biết được? Bằng cách xác định từ chúng tôi đang sử dụng. Quyền thừa kế là tài sản mà các thành viên thừa kế của một loại cũng là thành viên của loại khác. Theo định nghĩa này, rõ ràng một lớp thực hiện một giao diện đã kế thừa tất cả các phương thức của giao diện; Chỉ cần nhìn vào lớp và giao diện và bạn sẽ thấy rằng trong một chương trình chính xác, họ có cùng các thành viên.
Eric Lippert

Tôi đã bỏ chọn và để lại nhiều nhầm lẫn.
RajeeV VenkaT

18
Đối với những gì nó có giá trị, tôi nghĩ rằng bạn dành nhiều thời gian cho một định nghĩa từ sẽ không mang lại cho bạn nhiều lợi ích. Vào cuối ngày, tất cả chúng ta đều biết việc triển khai một giao diện có nghĩa là gì, và liệu nó có được coi là "thừa kế" hay không phần lớn đối với công việc hàng ngày của bạn.
Robert Harvey

3
Tôi (hầu hết) đồng ý với Robert. Tôi nghĩ rằng có giá trị thực sự trong việc hiểu ý nghĩa kỹ thuật chính xác của các từ biệt ngữ khi chúng được sử dụng trong các bối cảnh khác nhau. Nhưng Robert nói đúng rằng lợi ích lớn hơn nhiều để hiểu được tác động thực tế! Làm thế nào bạn có thể sử dụng kế thừa để làm cho mã của bạn an toàn hơn? Thử nghiệm nhiều hơn? Tái sử dụng nhiều hơn? Linh hoạt hơn? Và như vậy. Biết rằng các thành viên của các loại cơ sở cũng là thành viên của các loại dẫn xuất là tuyệt vời, nhưng tốt hơn hết là vẫn biết cách sử dụng nó một cách hiệu quả.
Eric Lippert

Câu trả lời:


78

CẬP NHẬT: Tôi đã sửa đổi câu trả lời này. Một số điểm tốt đã được nêu ra trong các ý kiến ​​xứng đáng được gọi ra.

Nếu lớp của tôi thực hiện một giao diện thì tôi có thể nói rằng tôi đang theo kế thừa không?

Nó không hoàn toàn rõ ràng những gì bạn có nghĩa là "theo thừa kế". Hãy hỏi một câu hỏi hơi khác nhau?

Thừa kế là gì?

  • Khi các thành viên của một loại X được coi là thành viên của một loại Y, những thành viên của Y được thừa hưởng từ X .
  • Có một mối quan hệ thừa kế giữa một số loại; nghĩa là, đối với một số loại X và Y, chúng ta nói "Y kế thừa từ X".

Đây là những khác biệt tinh tế. Điều đó thật đáng tiếc vì nó khó hiểu.

Những nhầm lẫn thường phát sinh từ sự phân biệt tinh tế này?

Nhầm lẫn có thể phát sinh vì mọi người nghĩ về thừa kế như một cơ chế để chia sẻ chi tiết thực hiện. Mặc dù nó một cơ chế như vậy, cơ chế đó hoạt động bằng cách chia sẻ các thành viên . Những thành viên không cần phải thực hiện! Như chúng ta sẽ thấy, chúng có thể trừu tượng.

Cá nhân tôi sẽ hạnh phúc hơn nếu các đặc tả Java và C # sử dụng một từ khác ngoài "kế thừa" để mô tả mối quan hệ giữa các phương thức và các lớp giao diện, để tránh sự nhầm lẫn này. Nhưng họ không, và chúng tôi phải suy luận từ các thông số kỹ thuật, không chống lại họ.

Trong Java, các thành viên giao diện được kế thừa bởi các lớp thực hiện chúng?

Vâng, một số là. Xem phần đặc tả Java 8.4.8, mà tôi trích dẫn ở đây để thuận tiện cho bạn.

Một lớp C kế thừa từ siêu lớp trực tiếp của nó và siêu giao diện trực tiếp tất cả các phương thức trừu tượng và mặc định m mà tất cả những điều sau đây là đúng: [...]

Nếu bạn nói rằng một lớp thực hiện một giao diện thì lớp đó kế thừa các phương thức trừu tượng và mặc định của giao diện đó . (Tất nhiên tôi đã bỏ qua các điều kiện tuân theo; xem thông số kỹ thuật để biết chi tiết. Đặc biệt, một lớp thực hiện một thành viên của giao diện không được coi là đã kế thừa thành viên đó. Một lần nữa, điều này có khó hiểu không?

Chúng ta thường nói trong Java rằng một lớp kế thừa từ một giao diện?

Thông thường chúng ta sẽ nói rằng một lớp thực hiện một giao diện. Như đã lưu ý ở trên, một lớp có thể kế thừa các thành viên từ một giao diện, nhưng vẫn không được cho là kế thừa từ giao diện. Đó là khó hiểu, có.

Sự phân biệt tinh tế này có quan trọng trong công việc hàng ngày không?

Điển hình là không. Kiểu phân tích cú pháp hẹp của đặc tả này hữu ích hơn cho các trình soạn thảo trình biên dịch so với dòng của các nhà phát triển kinh doanh. Điều quan trọng hơn để hiểu khi nào nên sử dụng một giao diện hơn là để có được một định nghĩa chính xác về "kế thừa từ".


4
Tôi không thể tranh luận với một tài liệu tham khảo kinh điển. Khi các thông số kỹ thuật khác nhau, như chúng nhất thiết phải làm, các thuật ngữ đơn giản trở nên quá tải về mặt ngữ nghĩa và mơ hồ ra khỏi bối cảnh. Câu hỏi được gắn thẻ javavì vậy đây là câu trả lời đúng, trừ khi OP có nghĩa là một số khác java:-)
Jodrell

5
Mặc dù câu hỏi được gắn thẻ với Java, tôi thấy có vấn đề khi trích dẫn một đặc tả ngôn ngữ cho một thuật ngữ chung. Nhiều ngôn ngữ có giao diện và thông số ngôn ngữ của chúng có thể sử dụng một thuật ngữ khác, vì vậy sử dụng thuật ngữ dành riêng cho Java có thể gây nhầm lẫn khi nói chuyện với các nhà phát triển sử dụng X-Lang.
Thomas Owens

5
@ThomasOwens: Tôi đồng ý rằng kịch bản này là phổ biến và tôi hoàn toàn không đồng ý với kết luận của bạn. Giải pháp cho vấn đề giao tiếp mà bạn mô tả là giáo dục mọi người liên quan đến ý nghĩa chính xác của các từ trong ngữ cảnh có liên quan . Thông số kỹ thuật tồn tại để cung cấp sự rõ ràng này; sử dụng chúng!
Eric Lippert

5
Tại sao đặc tả ngôn ngữ Java sẽ có tiếng nói cuối cùng ở đây? Đặc tả ngôn ngữ thường yêu cầu những điều mà "nhà phát triển chung" không đồng ý với thuật ngữ.
Benjamin Gruenbaum

5
@BenjaminGruenbaum: Tôi không biết điều đó. Những nhà phát triển đó đã sai và họ thường tự mình "giáo dục" người khác về niềm tin sai lầm của họ. Bạn sẽ không tin số lượng sách ngôn ngữ lập trình mà tôi phải sửa vì các tác giả có một số niềm tin hoàn toàn điên rồ về VB, C #, JavaScript, v.v., không có cách nào chính xác. (Jon Skeet không nằm trong số họ; C # Trong Depth là đúng ngay từ đầu Chưa bao giờ tôi làm quá ít ý kiến về một cuốn sách mà vẫn gạt trả tiền!.)
Eric Lippert

26

Kế thừa có nghĩa là viết một lớp con mới cho siêu lớp. Viết một lớp mới đối với một giao diện đang thực hiện giao diện đó. (Và viết một giao diện mới dựa trên giao diện cũ sẽ mở rộng giao diện đó.)

Thuật ngữ đúng duy nhất áp dụng cho cả ba khả năng là phân nhóm . Không phải mọi kiểu con là một lớp con.


1
Sách GoF dường như xem xét thuật ngữ phù hợp kế thừa giao diện để mô tả phân nhóm (Lớp 1.6 so với Kế thừa giao diện)
gnat

"Tôi đã từng tham dự một cuộc họp nhóm người dùng Java, nơi James Gosling (nhà phát minh Java) là diễn giả nổi bật. Trong phiên hỏi đáp đáng nhớ, có người hỏi anh ta:" Nếu bạn có thể làm lại Java, bạn sẽ thay đổi điều gì? " rời khỏi các lớp học, "anh ấy trả lời. Anh ấy giải thích rằng vấn đề thực sự không phải là các lớp, mà là kế thừa thực hiện (mối quan hệ mở rộng). Kế thừa giao diện (mối quan hệ thực hiện) là tốt hơn. Bạn nên tránh kế thừa thực hiện bất cứ khi nào có thể." javaworld.com/article/2073649/core-java/ từ
ricardoramos

1

Với các lớp con , bạn

  • kế thừa trạng thái của siêu lớp (tất cả các biến thể hiện, cho dù bạn có nhìn thấy chúng hay không)
  • kế thừa triển khai thực tế (tất cả các phương pháp không trừu tượng)

Với các giao diện , bạn hoàn thành một hợp đồng bằng cách thực hiện các phương thức khai báo.

Đó là cách cổ điển để xem xét nó. Bây giờ với Java 8, các giao diện trở thành một hỗn hợp:

  • bạn vẫn không kế thừa trạng thái (vì giao diện vẫn không có biến thể hiện)
  • bây giờ bạn có thể kế thừa các cài đặt mặc định từ giao diện

Việc triển khai một giao diện mà tất cả các phương thức của nó có các cài đặt mặc định vẫn được tính là 'hiện thực', hay đúng hơn là phần mở rộng? Tôi không thể nói. Vì trường hợp này khá xa vời (điều này thực sự cho phép đa kế thừa không trạng thái), tôi vẫn chỉ sử dụng 'thừa kế' với các lớp con.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.