Phương thức nào không thể kế thừa trong Java?
Kế thừa Java định nghĩa mối quan hệ is-a giữa một lớp cha và các lớp con của nó. Điều này có nghĩa là một Đối tượng của lớp con có thể được sử dụng ở bất cứ nơi nào có thể sử dụng đối tượng của lớp cha. Kế thừa lớp trong Java được sử dụng để xây dựng các Lớp mới từ các Lớp hiện có. Quan hệ thừa kế mang tính bắc cầu. nếu Lớp x mở rộng Lớp y, thì Lớp z, mở rộng Lớp x, cũng sẽ kế thừa từ Lớp y Show
Ví dụ: một Lớp xe hơi có thể kế thừa một số thuộc tính từ một Lớp xe nói chung. Ở đây chúng tôi thấy rằng Lớp cơ sở là Lớp xe và lớp con là Lớp xe cụ thể hơn. Một lớp con phải sử dụng mệnh đề mở rộng để dẫn xuất từ một siêu lớp phải được viết trong tiêu đề của định nghĩa lớp con. Lớp con kế thừa các thành viên của lớp cha và do đó thúc đẩy tái sử dụng mã. Bản thân lớp con có thể thêm hành vi và thuộc tính mới của nó. java. lang thang. Lớp đối tượng luôn đứng đầu bất kỳ hệ thống phân cấp kế thừa Lớp nào Điều gì là không thể khi sử dụng Kế thừa lớp Java?
cái này và siêu từ khóa Hai từ khóa this và super giúp bạn đặt tên rõ ràng cho trường hoặc Phương thức mà bạn muốn. Sử dụng từ khóa này và siêu bạn có toàn quyền kiểm soát việc gọi một Phương thức hoặc trường trong cùng một Lớp hay gọi từ lớp cha trực tiếp. từ khóa này được sử dụng làm tham chiếu đến Đối tượng hiện tại, là một thể hiện của Lớp hiện tại. Từ khóa super cũng tham chiếu đến Đối tượng hiện tại, nhưng là một thể hiện của lớp cha của lớp hiện tại từ khóa này tham chiếu đến Đối tượng hiện tại và rất hữu ích trong các tình huống khi một biến cục bộ ẩn hoặc che khuất một trường có cùng tên. Nếu một Phương thức cần chuyển Đối tượng hiện tại sang một Phương thức khác, thì nó có thể làm như vậy bằng cách sử dụng tham chiếu này. Lưu ý rằng tham chiếu này không thể được sử dụng trong ngữ cảnh tĩnh, vì mã tĩnh không được thực thi trong ngữ cảnh của bất kỳ Đối tượng nào Trong số các khái niệm quan trọng nhất trong lập trình hướng đối tượng là các khái niệm về kế thừa và đa hình. Kế thừa lớp là cơ chế theo đó một lớp có được (kế thừa) các phương thức và biến của các lớp cha của nó. Hãy xem xét một ví dụ về hình thức thừa kế tự nhiên. Giống như ngựa kế thừa các thuộc tính và hành vi liên quan đến động vật có vú và động vật có xương sống, một lớp con Java kế thừa các thuộc tính và hành vi của các lớp cha của nó Như thể hiện trong sơ đồ trên, gốc của hệ thống phân cấp, luôn được hiển thị ở trên cùng, lớp 0 chứa các thuộc tính chung nhất, chẳng hạn như còn sống và có thể di chuyển. Tất cả các loài động vật chia sẻ các thuộc tính này. Lớp động vật có xương sống là một loại động vật chuyên biệt hơn một chút, trong đó động vật có xương sống có xương sống. Tương tự, lớp động vật có vú là một chuyên ngành sâu hơn so với động vật có xương sống ở chỗ động vật có vú là loài máu nóng và nuôi con non. Cuối cùng, lớp ngựa là một chuyên ngành sâu hơn so với lớp động vật có vú, trong đó tất cả các con ngựa đều có bốn chân. Một số động vật có vú, chẳng hạn như con người và chim cánh cụt, không có bốn chân. Do đó, nhờ vị trí của lớp trong hệ thống phân cấp này, chúng ta có thể suy ra rằng ngựa là động vật có xương sống bốn chân, di chuyển, sống, có máu nóng và nuôi con non.Chúng tôi đã cố tình sử dụng một ví dụ từ thế giới tự nhiên để chỉ ra rằng khái niệm kế thừa trong Java được lấy cảm hứng từ đối tác của nó trong thế giới tự nhiên. Nhưng chính xác thì khái niệm kế thừa áp dụng cho Java (và cho các ngôn ngữ hướng đối tượng khác) như thế nào? Sử dụng một phương pháp kế thừaTrong Java, các phương thức đối tượng công khai và được bảo vệ cũng như các biến đối tượng của một lớp cha được kế thừa bởi tất cả các lớp con của nó. Điều này có nghĩa là các đối tượng thuộc các lớp con có thể sử dụng các biến và phương thức kế thừa như của chính chúng. Ví dụ: tất cả các lớp Java đều là lớp con của lớp 2, đây là lớp tổng quát nhất trong hệ thống phân cấp lớp của Java. Một phương thức public được định nghĩa trong lớp 2 là phương thức 4. Bởi vì mọi lớp trong hệ thống phân cấp Java đều là lớp con của 2, nên mọi lớp đều kế thừa phương thức 4. Do đó, 4 có thể được sử dụng với bất kỳ đối tượng Java nàoGiả sử chúng ta định nghĩa một lớp Sinh viên như sau
Hình trên cho thấy mối quan hệ giữa lớp này và lớp 2. Là một lớp con của Object, lớp 9 kế thừa phương thức 4. Do đó, đối với một đối tượng Sinh viên nhất định, chúng ta có thể gọi 4 của nó như sau 2Cái này hoạt động ra sao? Lưu ý trong ví dụ này rằng biến stu được khai báo là kiểu 9 và được gán một thể hiện của lớp 9. Khi biểu thức 76 được thực thi, đầu tiên Java sẽ tìm trong lớp 9 để tìm định nghĩa của phương thức 4. Không tìm thấy cái nào ở đó, nó sẽ tìm kiếm trong hệ thống phân cấp lớp 9 (Hình. số 8. 2) cho đến khi tìm thấy định nghĩa công khai hoặc được bảo vệ của phương thức 4. Trong trường hợp này, nó tìm thấy một phương thức 4 trong lớp Đối tượng và nó thực thi triển khai của 4 đóGhi đè một phương thức kế thừaViệc triển khai mặc định của 4 trả về tên của lớp đối tượng và địa chỉ (e. g. 54) nơi đối tượng được lưu trữ trong bộ nhớ. Tuy nhiên, loại kết quả này quá chung chung và không đặc biệt hữu íchPhương thức 4 được thiết kế để ghi đè—nghĩa là được định nghĩa lại trong các lớp con của Đối tượng. Ghi đè 4 trong một lớp con cung cấp một biểu diễn chuỗi tùy chỉnh của các đối tượng trong lớp con đóĐể ghi đè 4 cho lớp 9, hãy thêm định nghĩa phương thức sau vào lớp 9
Với sự thay đổi này, hệ thống phân cấp lớp 9 đã sửa đổi được hiển thị trong hình bên dưới. Lưu ý rằng cả Object và 9 đều chứa các triển khai của 4. Bây giờ khi biểu thức 76 được gọi, đầu ra sau đây, nhiều thông tin hơn, sẽ được tạo 7Trong trường hợp này, khi Java gặp lệnh gọi phương thức 76, nó sẽ gọi phương thức 4 mà nó tìm thấy trong lớp 9Liên kết tĩnh và liên kết độngCơ chế mà Java sử dụng trong các ví dụ này được gọi là liên kết động, trong đó liên kết giữa lệnh gọi phương thức và triển khai phương thức chính xác được thực hiện trong thời gian chạy. Trong liên kết động, một cuộc gọi phương thức được liên kết với việc triển khai đúng phương thức trong thời gian chạy bởi Máy ảo Java (JVM) Liên kết động tương phản với liên kết tĩnh, cơ chế mà trình biên dịch Java giải quyết mối liên kết giữa lệnh gọi phương thức và triển khai phương thức chính xác khi chương trình được biên dịch. Để liên kết động hoạt động, JVM cần duy trì một số loại biểu diễn của hệ thống phân cấp lớp Java, bao gồm các lớp do lập trình viên định nghĩa. Khi JVM gặp một lệnh gọi phương thức, nó sẽ sử dụng thông tin về hệ thống phân cấp lớp để liên kết lệnh gọi phương thức với việc triển khai đúng phương thức đó Trong Java, tất cả các lệnh gọi phương thức đều sử dụng liên kết động ngoại trừ các phương thức được khai báo là cuối cùng hoặc riêng tư. Các phương thức cuối cùng không thể bị ghi đè, vì vậy việc khai báo một phương thức là cuối cùng có nghĩa là trình biên dịch Java có thể liên kết nó với cách triển khai chính xác. Tương tự, các phương thức riêng tư không được kế thừa và do đó không thể ghi đè trong một lớp con. Trên thực tế, các phương thức riêng tư là các phương thức cuối cùng và trình biên dịch có thể thực hiện liên kết tại thời điểm biên dịch đa hìnhCơ chế liên kết động của Java, còn được gọi là liên kết muộn hoặc liên kết thời gian chạy, dẫn đến cái được gọi là tính đa hình. Tính đa hình là một tính năng của các ngôn ngữ hướng đối tượng, theo đó cùng một lệnh gọi phương thức có thể dẫn đến các hành vi khác nhau tùy thuộc vào loại đối tượng mà lệnh gọi phương thức được thực hiện. Thuật ngữ đa hình có nghĩa là, theo nghĩa đen, có nhiều (đa) hình dạng (hình thái). Đây là một ví dụ đơn giản 5Biến 17 được khai báo là kiểu 2. Đây là loại tĩnh hoặc khai báo của nó. Kiểu tĩnh của một biến không bao giờ thay đổi. Tuy nhiên, một biến cũng có kiểu thực hoặc kiểu động. Đây là loại thực tế của đối tượng đã được gán cho biến. Như bạn đã biết, một biến Đối tượng có thể được gán đối tượng từ bất kỳ lớp con Đối tượng nào. Trong câu lệnh thứ hai, 17 được gán một đối tượng Sinh viên. Do đó, tại thời điểm này trong chương trình, kiểu thực sự của biến 17 là Sinh viên. Khi 51 được gọi ở dòng thứ ba, Java bắt đầu tìm kiếm phương thức 4 tại lớp Sinh viên, vì đó là kiểu thực của biếnỞ dòng thứ tư, chúng ta gán một đối tượng lớp 53 khác cho 17, do đó thay đổi kiểu thực tế của nó thành 53. Do đó, khi 56() được gọi ở dòng cuối cùng, phương thức 4 bị ràng buộc với triển khai được tìm thấy trong lớp 53Do đó, chúng ta thấy rằng cùng một biểu thức, 51, được liên kết luân phiên với hai triển khai 4 khác nhau, dựa trên loại thực tế của đối tượng, 17, trên đó nó được gọi. Đây là đa hìnhĐiểm quan trọng ở đây là tính đa hình xảy ra khi một phương thức bị ghi đè được gọi trên một biến siêu lớp, e. g. , 17. Trong trường hợp như vậy, việc triển khai phương thức thực tế được gọi được xác định trong thời gian chạy. Việc xác định phụ thuộc vào loại đối tượng được gán cho biến. Do đó, chúng tôi nói rằng cuộc gọi phương thức 51 là đa hình vì nó được liên kết với các triển khai khác nhau của 4 tùy thuộc vào loại thực tế của đối tượng được liên kết với 17Đa hình và thiết kế hướng đối tượngBây giờ chúng ta đã hiểu cách hoạt động của tính kế thừa và tính đa hình trong Java, sẽ rất hữu ích khi xem xét một ví dụ minh họa cách các cơ chế này có thể hữu ích trong việc thiết kế các lớp và phương thức. Các phương thức 06 và 07 là ví dụ về các phương thức quá tải, nghĩa là các phương thức có cùng tên nhưng danh sách tham số khác nhau. Hãy nhớ rằng chữ ký của một phương thức liên quan đến tên của nó, cộng với loại, số và thứ tự của các tham số của nó. Các phương thức có cùng tên nhưng khác tham số được gọi là quá tảiDưới đây là chữ ký của một số phương thức print() và println() khác nhau 1Về cơ bản, có một phương thức 08 và 09 cho mọi loại dữ liệu nguyên thủy, cộng với các phương thức để in bất kỳ loại đối tượng nào. Khi Java gặp một biểu thức liên quan đến 08 hoặc 09, nó sẽ chọn phương thức cụ thể để gọi. Để xác định phương thức chính xác, Java dựa vào sự khác biệt trong chữ ký của các phương thức 08 khác nhau. Ví dụ: vì đối số của nó là một 83, nên biểu thức 84 được liên kết với phương thức có chữ ký là 85 vì tham số của nó là một 83Sử dụng public String toString() { return "My name is " + name + " and I am a Student."; } 1 để tham khảo SuperclassMột câu hỏi có thể xảy ra với bạn là. Khi bạn ghi đè phương thức mặc định 4, thì có thể gọi phương thức mặc định trên đối tượng Sinh viên không? . Ví dụ, giả sử rằng trong lớp Student, bạn muốn nối kết quả của cả phương thức mặc định và phương thức mới 4. Biểu thức sau đây sẽ thực hiện điều đó 5Từ khóa 1 chỉ định rằng 4 đầu tiên là từ khóa được triển khai trong siêu lớp. 4 thứ hai đơn giản đề cập đến phiên bản được triển khai trong lớp. Chúng ta sẽ xem thêm các ví dụ về cách sử dụng từ khóa super trong các phần sauKế thừa và ConstructorCơ chế kế thừa của Java áp dụng cho các biến và phương thức thể hiện công khai và được bảo vệ của một lớp. Nó không áp dụng cho các hàm tạo của một lớp. Để minh họa một số ý nghĩa của tính năng ngôn ngữ này, hãy định nghĩa một lớp con của 9 được gọi là 15 0Bởi vì 15 là một lớp con của 9, nên nó kế thừa các phương thức và biến thể hiện công khai và được bảo vệ từ 9. Vì vậy, một 15 có một biến đối tượng là name và nó có một phương thức 200 công khai. Nhớ lại rằng một phần tử được bảo vệ, chẳng hạn như biến tên trong lớp 9, chỉ có thể truy cập được trong lớp và các lớp con của nó. Không giống như các phần tử công khai, nó không thể truy cập được đối với các lớp khácLưu ý cách chúng tôi đã triển khai hàm tạo 202. Bởi vì các hàm tạo của lớp cha không được kế thừa, chúng ta phải triển khai hàm tạo này trong lớp con nếu chúng ta muốn có thể gán tên của CollegeStudent trong quá trình xây dựng đối tượng. Cuộc gọi phương thức, 203, được sử dụng để gọi phương thức khởi tạo của lớp bậc trên và chuyển nó vào ____1204, tên của học sinh. Hàm tạo của lớp bậc trên sau đó sẽ gán 204 cho biến tênNhư chúng ta đã lưu ý, một lớp con không kế thừa các hàm tạo từ các lớp cha của nó. Tuy nhiên, nếu hàm tạo của lớp con không gọi hàm tạo của lớp bậc trên một cách rõ ràng, thì Java sẽ tự động gọi hàm tạo của lớp bậc trên mặc định—trong trường hợp này là 206. Theo hàm tạo siêu lớp mặc định, chúng tôi muốn nói đến hàm tạo không có tham số. Đối với một lớp con nằm dưới một vài lớp trong hệ thống phân cấp, việc gọi hàm tạo 206 tự động này sẽ được lặp lại lên trên trong toàn bộ hệ thống phân cấp của lớp. Do đó, khi một 15 được xây dựng, Java sẽ tự động gọi 209 và 210. Lưu ý rằng nếu một trong các lớp cha không chứa hàm tạo mặc định, điều này sẽ dẫn đến lỗi cú phápNếu bạn nghĩ về điều này, nó có ý nghĩa. Làm thế nào khác các yếu tố kế thừa của đối tượng sẽ được tạo ra? . Hàm tạo 15 sau đó mở rộng định nghĩa của lớp 9. Tương tự, để một đối tượng 9 có các thuộc tính chung cho tất cả các đối tượng, một thể hiện 2 phải được tạo và sau đó mở rộng thành một 9Do đó, trừ khi một hàm tạo gọi một hàm tạo của lớp bậc trên một cách rõ ràng, Java sẽ tự động gọi các hàm tạo của lớp bậc trên mặc định. Nó thực hiện điều này trước khi thực thi mã trong hàm tạo của chính nó. Ví dụ: nếu bạn có hai lớp, 220 và 221, trong đó 221 là lớp con của 220, thì bất cứ khi nào bạn tạo một thể hiện của 221, trước tiên, Java sẽ gọi hàm tạo của 220 trước khi thực thi mã trong hàm tạo của 221 để lớp cơ sở được khởi tạo. Do đó, hành vi mặc định của Java trong quá trình xây dựng 221 tương đương với việc triển khai hàm tạo của 221 sau đây 8Ví dụ, 1Nó sẽ in 20Các lớp trừu tượng, giao diện và đa hìnhTrong Java, có ba loại đa hình
Trong phần trước chúng ta đã thấy các ví dụ về loại đa hình đầu tiên. Tất cả các dạng đa hình đều dựa trên cơ chế liên kết động của Java. Trong phần này, chúng tôi sẽ phát triển một ví dụ minh họa hai loại đa hình khác và thảo luận về một số hàm ý thiết kế liên quan đến việc chọn một hoặc một cách tiếp cận khác Triển khai một phương thức trừu tượngMột tính năng quan trọng của tính đa hình là khả năng gọi một phương thức đa hình đã được định nghĩa một cách trừu tượng trong lớp cha. Để minh họa tính năng này, chúng tôi sẽ phát triển một hệ thống phân cấp các động vật mô phỏng tạo ra âm thanh đặc trưng của động vật, một ví dụ được sử dụng rộng rãi để minh họa tính đa hình Như chúng ta đã biết từ thời thơ ấu, động vật có những cách nói đặc biệt. Con bò kêu “moo”; . Hãy thiết kế một hệ thống cấp bậc của các loài động vật mô phỏng đặc điểm này bằng cách in các âm thanh đặc trưng mà các loài động vật này tạo ra. Chúng tôi muốn thiết kế các lớp học của mình sao cho bất kỳ con vật nào cũng sẽ trả về một cái gì đó giống như “Tôi là một con bò và tôi đi moo,” khi chúng tôi gọi phương thức 4. Hơn nữa, chúng tôi muốn thiết kế bộ sưu tập các lớp này sao cho nó có thể mở rộng—nghĩa là, để chúng tôi có thể tiếp tục thêm các loài động vật mới vào bầy thú của mình mà không phải thay đổi bất kỳ mã nào trong các lớp khácHình dưới đây cung cấp một bản tóm tắt về thiết kế chúng tôi sẽ thực hiện. Lớp 0 là một lớp trừu tượng. Đó là lý do tại sao tên của nó được in nghiêng trong hình. Lý do mà lớp này trừu tượng là vì phương thức 231 của nó là một phương thức trừu tượng, là một định nghĩa phương thức không chứa phần triển khai. Nghĩa là, định nghĩa phương thức chỉ chứa chữ ký của phương thức, không phải phần thân của nó. Bất kỳ lớp nào chứa một phương thức trừu tượng, chính nó phải được khai báo trừu tượngĐây là định nghĩa của lớp 0 21Lưu ý cách chúng ta khai báo phương thức trừu tượng (______1231) và lớp trừu tượng. Bởi vì một hoặc nhiều phương thức của nó không được triển khai, một lớp trừu tượng không thể được khởi tạo. Đó là, bạn không thể nói 22Mặc dù không cần thiết, chúng tôi cung cấp cho lớp Animal một hàm tạo. Nếu chúng ta bỏ qua điều này, Java sẽ cung cấp một hàm tạo mặc định sẽ được gọi khi các lớp con Animal được tạo Java có các quy tắc sau về việc sử dụng các phương thức và lớp trừu tượng
Mặc dù một phương thức trừu tượng không được triển khai trong lớp cha, nhưng nó có thể được gọi trong lớp cha. Thật vậy, hãy lưu ý cách phương thức 4 gọi phương thức trừu tượng 231. Lý do điều này hoạt động trong Java là do cơ chế liên kết động. Phương thức 231 đa hình sẽ được định nghĩa trong các lớp con Animal khác nhau. Khi phương thức 237 được gọi, Java sẽ quyết định gọi phương thức 231 thực tế nào dựa trên lớp con của Animal có liên quan 23Trong mỗi trường hợp, lớp con mở rộng lớp 0 và cung cấp phương thức khởi tạo riêng và triển khai phương thức 231 của riêng nó. Lưu ý rằng trong các hàm tạo tương ứng của chúng, chúng ta có thể tham khảo biến thể hiện loại, được kế thừa từ lớp 0. Bằng cách khai báo loại là một biến được bảo vệ, nó được kế thừa bởi tất cả các lớp con của 0 nhưng bị ẩn khỏi tất cả các lớp khác. Mặt khác, nếu loại đã được khai báo công khai, nó sẽ được kế thừa bởi 0 lớp con, nhưng nó cũng có thể được truy cập bởi mọi lớp khác, điều này sẽ vi phạm nguyên tắc ẩn thông tinVới những định nghĩa này, giờ đây chúng ta có thể chứng minh sức mạnh và tính linh hoạt của tính kế thừa và tính đa hình. Xét đoạn mã sau 24Đầu tiên chúng ta tạo một đối tượng Cow và sau đó gọi phương thức (kế thừa) 4 của nó. Nó trả về, “Tôi là một con bò và tôi đi moo. ” Sau đó, chúng tôi tạo một đối tượng Cat và gọi phương thức (kế thừa) 4 của nó, phương thức này trả về, “Tôi là một con mèo và tôi kêu meo meo. ” Nói cách khác, Java có thể xác định cách triển khai speak() thích hợp trong thời gian chạy trong từng trường hợp. Việc gọi phương thức speak() trừu tượng trong phương thức 237 là một dạng đa hình thứ haiLợi thế của đa hình ở đây là gì? . Chúng ta có thể định nghĩa và sử dụng các lớp con Animal hoàn toàn mới mà không cần định nghĩa lại hoặc biên dịch lại các lớp còn lại trong hệ thống phân cấp. Lưu ý rằng phương thức 4 trong lớp Animal không cần biết loại lớp con Animal nào sẽ thực thi phương thức speak() của nó. Phương thức 4 sẽ hoạt động chính xác cho bất kỳ lớp con nào của Animal vì mọi lớp con không trừu tượng của Animal phải triển khai phương thức speak()Để đánh giá tốt hơn về tính linh hoạt và khả năng mở rộng của thiết kế này, có thể hữu ích khi xem xét một thiết kế thay thế không sử dụng tính đa hình. Một giải pháp thay thế như vậy là định nghĩa từng lớp con Động vật bằng phương thức nói của riêng nó. Một con Bò sẽ có phương thức moo(); . Với thiết kế này, chúng ta có thể sử dụng câu lệnh switch để chọn phương thức gọi thích hợp. Ví dụ: xem xét định nghĩa phương thức sau 25Trong ví dụ này, chúng tôi giới thiệu toán tử 249, là toán tử boolean được tích hợp sẵn. Nó trả về true nếu đối tượng ở phía bên trái của nó là một thể hiện của lớp ở phía bên phải của nóPhương pháp 250 sẽ tạo ra kết quả ít nhiều giống nhau. Nếu bạn gọi talk( 251), nó sẽ trả về “I am a cow and I go moo. ” Tuy nhiên, với thiết kế này, không thể mở rộng phân cấp Animal mà không viết lại và biên dịch lại phương thức 250Do đó, một trong những ưu điểm chính của việc sử dụng tính đa hình là tính linh hoạt và khả năng mở rộng tuyệt vời mà nó mang lại. Chúng ta có thể định nghĩa các lớp con Animal mới và định nghĩa các phương thức 231 của chúng. Tất cả những thứ này sẽ hoạt động với phương thức 4 trong lớp Động vật mà không cần phải sửa lại phương thức đóMột ưu điểm khác của việc sử dụng các phương thức trừu tượng là khả năng kiểm soát mà nó mang lại cho người thiết kế hệ thống phân cấp Động vật. Bằng cách biến nó thành một lớp trừu tượng với phương thức trừu tượng 231, bất kỳ lớp con Động vật không trừu tượng nào cũng phải triển khai phương thức 231. Điều này mang lại khả năng dự đoán cao cho các lớp con trong hệ thống phân cấp, giúp sử dụng chúng dễ dàng hơn trong các ứng dụngTheo các ví dụ trong phần này, hãy định nghĩa một phân lớp Động vật có tên là Lợn, lớp con này sẽ “oink. ” Chỉ ra cách bạn sẽ phải sửa đổi phương thức 250 được xác định ở trên để kết hợp lớp PigTriển khai giao diện JavaDạng đa hình thứ ba là kết quả thông qua việc triển khai các giao diện Java, giống như các lớp nhưng chỉ chứa các định nghĩa phương thức trừu tượng và các biến hằng (cuối cùng). Một giao diện không thể chứa các biến thể hiện Người thiết kế giao diện chỉ định phương thức nào sẽ được triển khai bởi các lớp triển khai giao diện. Điều này tương tự như những gì chúng ta đã làm khi triển khai phương thức speak() trừu tượng trong ví dụ động vật. Sự khác biệt giữa việc triển khai một phương thức từ một giao diện và từ một lớp cha trừu tượng là một lớp con mở rộng một lớp cha trừu tượng nhưng nó thực thi một giao diện Cơ chế giao diện của Java cho chúng ta một cách khác để thiết kế các phương thức đa hình. Để xem điều này hoạt động như thế nào, chúng tôi sẽ cung cấp một thiết kế thay thế cho hệ thống phân cấp động vật của chúng tôi. Thay vì định nghĩa speak() như một phương thức trừu tượng trong lớp cha Animal, chúng ta sẽ định nghĩa nó như một phương thức trừu tượng trong giao diện Speakable 26Lưu ý sự khác biệt giữa định nghĩa Động vật này và định nghĩa trước đó. Phiên bản này không còn chứa phương thức trừu tượng 231. Do đó, bản thân lớp không phải là lớp trừu tượng. Tuy nhiên, vì phương thức 231 không được khai báo trong lớp này nên chúng ta không thể gọi phương thức 231 trong phương thức 4, trừ khi chúng ta ép kiểu đối tượng này thành đối tượng SpeakableVới những định nghĩa này, giờ đây các lớp con Animal sẽ mở rộng lớp Animal và triển khai giao diện Speakable 27Để triển khai giao diện Java, người ta phải cung cấp triển khai phương thức cho từng phương thức trừu tượng trong giao diện. Trong trường hợp này chỉ có một phương thức trừu tượng, phương thức speak() Lưu ý, một lần nữa, biểu thức từ Animal. lớp toString() 28chuyển đối tượng này thành đối tượng 262. Lý do bắt buộc phải sử dụng phương thức này là vì Động vật không nhất thiết phải có phương thức 231. Một phương thức 231 không được định nghĩa trong lớp Animal. Tuy nhiên, lớp con Cat của Animal thực hiện phương thức sleep() như một phần của giao diện Speakable của nó. Do đó, để gọi 231 trên một đối tượng từ một trong các lớp con Animal, đối tượng đó phải thực sự là một Speakable và chúng ta phải thực hiện ép kiểu như được hiển thị ở đâyNhân tiện, điều này minh họa rằng một 266, nhờ mở rộng lớp Animal và triển khai giao diện 262, vừa là một 0 vừa là một 262. Nói chung, một lớp thực hiện một giao diện, có giao diện đó là một trong các loại của nó. Bản thân việc triển khai giao diện là một hình thức kế thừa. Một lớp Java có thể là một lớp con trực tiếp của chỉ một lớp cha. Nhưng nó có thể thực hiện bất kỳ số lượng giao diện nàoVới các định nghĩa này của các lớp con 270 và 266, đoạn mã sau sẽ tạo ra kết quả giống như trong phần trước
Loại phương thức nào Không thể được kế thừa?Các phương thức được khai báo là riêng tư trong lớp công khai hoặc được bảo vệ , không thể kế thừa. Constructor không thể kế thừa. Các phương thức cuối cùng không thể bị ghi đè. Các phương thức tĩnh không thể bị ghi đè, nhưng có thể được khai báo lại trong một lớp con.
Khi một lớp Không thể kế thừa trong Java?Lớp cuối cùng không thể kế thừa. Nếu một lớp không phải là cuối cùng chứa phương thức cuối cùng thì nó có thể được kế thừa nhưng không thể ghi đè trong lớp con. |