Nếu một lớp chứa một phương thức trừu tượng ________.
Các lớp trong Java tồn tại trong một hệ thống phân cấp. Một lớp trong Java có thể được khai báo như một lớp con của một lớp khác bằng cách sử dụng từ khóa 0. Một lớp con kế thừa các biến và phương thức từ lớp cha của nó và có thể sử dụng chúng như thể chúng được khai báo trong chính lớp con đó Show
Trong ví dụ này, một đối tượng kiểu 1 có cả biến thể hiện 2 và phương thức 3. Họ được thừa hưởng từ 4 Một lớp chỉ có thể mở rộng một lớp khác. Để sử dụng thuật ngữ thích hợp, Java cho phép kế thừa duy nhất việc triển khai lớp. Ở phần sau của chương này, chúng ta sẽ nói về các giao diện, thay thế cho đa kế thừa vì nó chủ yếu được sử dụng trong các ngôn ngữ khác Một phân lớp có thể được phân lớp tiếp theo. Thông thường, phân lớp chuyên biệt hóa hoặc tinh chỉnh một lớp bằng cách thêm các biến và phương thức (bạn không thể loại bỏ hoặc ẩn các biến hoặc phương thức bằng cách phân lớp). Ví dụ
Lớp 5 là một loại 1 cuối cùng là một loại 4. Đối tượng 5 kế thừa tất cả các đặc điểm của đối tượng 1 và ngược lại, đối tượng 4. 5 cũng cung cấp hành vi bổ sung dưới dạng phương thức 42 và biến 43. Chúng ta có thể biểu thị mối quan hệ lớp trong sơ đồ, như trong Hình 6-1 Một lớp con kế thừa tất cả các thành viên của lớp cha của nó không được chỉ định là 44. Như chúng ta sẽ thảo luận ngay sau đây, các mức hiển thị khác ảnh hưởng đến việc các thành viên kế thừa của lớp có thể được nhìn thấy từ bên ngoài lớp và các lớp con của nó, nhưng ở mức tối thiểu, một lớp con luôn có cùng một tập hợp các thành viên hiển thị như lớp cha của nó. Vì lý do này, loại của một lớp con có thể được coi là một kiểu con của lớp cha của nó và các thể hiện của kiểu con có thể được sử dụng ở bất kỳ nơi nào cho phép các thể hiện của siêu kiểu. Xem xét ví dụ sau
Hình 6-1. Một hệ thống phân cấp lớp Ví dụ 5 46 trong ví dụ này có thể được gán cho biến loại 4 48 vì 5 là một kiểu con của 4. Tương tự, bất kỳ phương thức nào chấp nhận một đối tượng 4 cũng sẽ chấp nhận một thể hiện của một loại 5 hoặc bất kỳ loại 1 nào. Đây là một khía cạnh quan trọng của tính đa hình trong một ngôn ngữ hướng đối tượng như Java. Chúng ta sẽ xem nó có thể được sử dụng như thế nào để tinh chỉnh hành vi của một lớp, cũng như thêm các khả năng mới cho lớp đó Trong Chương 5, chúng ta đã thấy rằng một biến cục bộ cùng tên với một biến thể hiện sẽ che (ẩn) biến thể hiện. Tương tự, một biến thể hiện trong một lớp con có thể che khuất một biến thể hiện cùng tên trong lớp cha của nó, như minh họa trong Hình 6-2. Chúng tôi sẽ đề cập chi tiết về ẩn biến này ngay bây giờ để hoàn thiện và chuẩn bị cho các chủ đề nâng cao hơn, nhưng trong thực tế, bạn hầu như không bao giờ nên làm điều này. Trên thực tế, sẽ tốt hơn nhiều nếu cấu trúc mã của bạn để phân biệt rõ ràng các biến bằng cách sử dụng các tên hoặc quy ước đặt tên khác nhau Trong Hình 6-2, biến 2 được khai báo ở ba vị trí. dưới dạng biến cục bộ trong phương thức 85 của lớp 1, dưới dạng biến thể hiện của lớp 1 và dưới dạng biến thể hiện của lớp 4. Biến thực tế được chọn khi bạn tham chiếu nó trong mã sẽ phụ thuộc vào phạm vi mà chúng tôi đang làm việc và cách bạn đủ điều kiện tham chiếu đến nó Hình 6-2. Phạm vi của các biến bóng mờ Trong ví dụ trước, tất cả các biến đều cùng loại. Việc sử dụng các biến bóng mờ hợp lý hơn một chút sẽ liên quan đến việc thay đổi loại của chúng. Ví dụ, chúng ta có thể tạo bóng một biến 89 với một biến 30 trong một lớp con cần giá trị thập phân thay vì giá trị số nguyên. Chúng tôi có thể làm điều này mà không cần thay đổi mã hiện có bởi vì, như tên gọi của nó, khi chúng tôi ẩn các biến, chúng tôi không thay thế chúng mà thay vào đó che giấu chúng. Cả hai biến vẫn tồn tại; . Việc xác định các biến mà các phương thức khác nhau nhìn thấy xảy ra tại thời điểm biên dịch Đây là một ví dụ đơn giản 4 Trong ví dụ này, chúng tôi tạo bóng cho biến thể hiện 31 để thay đổi loại của nó từ 89 thành 30. [] Các phương thức được định nghĩa trong lớp 34 xem biến số nguyên 31, trong khi các phương thức được định nghĩa trong lớp 36 xem biến dấu phẩy động 31. Tuy nhiên, cả hai biến thực sự tồn tại trong một phiên bản nhất định của 36 và chúng có thể có các giá trị độc lập. Trên thực tế, bất kỳ phương thức nào mà 36 kế thừa từ 34 đều thực sự nhìn thấy biến số nguyên 31 Bởi vì cả hai biến đều tồn tại trong 36, nên chúng ta cần một cách để tham chiếu biến kế thừa từ 34. Chúng tôi làm điều đó bằng cách sử dụng từ khóa 84 làm từ hạn định trên tài liệu tham khảo 8 Bên trong 36, từ khóa 84 được sử dụng theo cách này sẽ chọn biến 31 được xác định trong siêu lớp. Chúng tôi sẽ giải thích việc sử dụng 84 đầy đủ hơn một chút Một điểm quan trọng khác về các biến bóng mờ liên quan đến cách chúng hoạt động khi chúng ta tham chiếu đến một đối tượng bằng một kiểu ít dẫn xuất hơn (kiểu cha). Ví dụ, chúng ta có thể gọi một đối tượng 36 là một 34 bằng cách sử dụng nó thông qua một biến kiểu 34. Nếu chúng ta làm như vậy và sau đó truy cập vào biến 31, chúng ta sẽ nhận được biến số nguyên chứ không phải số thập phân 3 Điều này cũng đúng nếu chúng ta truy cập đối tượng bằng cách truyền rõ ràng sang kiểu 34 hoặc khi chuyển một thể hiện vào một phương thức chấp nhận kiểu cha đó Để nhắc lại, tính hữu ích của các biến bóng tối bị hạn chế. Tốt hơn hết là trừu tượng hóa việc sử dụng các biến như thế này theo những cách khác hơn là sử dụng các quy tắc phạm vi phức tạp. Tuy nhiên, điều quan trọng là phải hiểu các khái niệm ở đây trước khi chúng ta nói về việc làm điều tương tự với các phương thức. Chúng ta sẽ thấy một loại hành vi khác và năng động hơn khi các phương thức che khuất các phương thức khác hoặc sử dụng thuật ngữ chính xác, ghi đè các phương thức khác Trong Chương 5, chúng ta đã thấy rằng chúng ta có thể khai báo các phương thức quá tải (i. e. , các phương thức có cùng tên nhưng khác số lượng hoặc kiểu đối số) trong một lớp. Lựa chọn phương thức quá tải hoạt động theo cách chúng tôi đã mô tả trên tất cả các phương thức có sẵn cho một lớp, bao gồm cả những phương thức kế thừa. Điều này có nghĩa là một lớp con có thể định nghĩa các phương thức quá tải bổ sung thêm vào các phương thức quá tải được cung cấp bởi một lớp cha Một lớp con có thể làm nhiều hơn thế; . Trong trường hợp đó, phương thức trong lớp con sẽ ghi đè phương thức trong lớp cha và thay thế hiệu quả việc triển khai của nó, như minh họa trong Hình 6-3. Ghi đè các phương thức để thay đổi hành vi của các đối tượng được gọi là đa hình kiểu con. Đó là cách sử dụng mà hầu hết mọi người nghĩ đến khi họ nói về sức mạnh của ngôn ngữ hướng đối tượng Hình 6-3. Ghi đè phương thức Trong Hình 6-3, 1 thay thế phương pháp 15 của 4, có lẽ để chuyên biệt hóa phương pháp cho hành vi của động vật có vú sinh con. [] Hành vi ngủ của đối tượng 5 cũng được ghi đè để khác với hành vi của đối tượng 4 chung, có lẽ để phù hợp với giấc ngủ ngắn của mèo. Lớp 5 cũng bổ sung các hành vi rừ rừ và săn chuột độc đáo hơn Từ những gì bạn đã thấy cho đến nay, các phương thức bị ghi đè có thể trông giống như các phương thức ẩn trong các lớp cha, giống như các biến vậy. Nhưng các phương thức bị ghi đè thực sự mạnh hơn thế. Khi có nhiều triển khai của một phương thức trong hệ thống phân cấp kế thừa của một đối tượng, thì phương thức trong lớp “có nguồn gốc cao nhất” (xa nhất trong hệ thống phân cấp) luôn ghi đè lên các phương thức khác, ngay cả khi chúng ta tham chiếu đến đối tượng thông qua tham chiếu của một trong các . [] Ví dụ: nếu chúng ta có một thể hiện 5 được gán cho một biến có kiểu tổng quát hơn là 4 và chúng ta gọi phương thức 82 của nó, thì chúng ta vẫn nhận được phương thức 82 được triển khai trong lớp 5, không phải phương thức trong lớp 4 8 Nói cách khác, đối với các mục đích của hành vi (các phương thức gọi), một 5 hoạt động giống như một 5, bất kể bạn có gọi nó như vậy hay không. Ở khía cạnh khác, biến 48 ở đây có thể hoạt động giống như một tham chiếu 4. Như chúng tôi đã giải thích trước đó, việc truy cập vào một biến bị che khuất thông qua tham chiếu 4 sẽ tìm thấy một triển khai trong lớp 4, không phải lớp 5. Tuy nhiên, vì các phương thức được định vị một cách linh hoạt, tìm kiếm các lớp con trước tiên, nên phương thức thích hợp trong lớp 5 được gọi, mặc dù chúng ta đang xử lý nó một cách tổng quát hơn như một đối tượng 4. Điều này có nghĩa là hành vi của các đối tượng là động. Chúng ta có thể xử lý các đối tượng chuyên biệt như thể chúng là các loại tổng quát hơn và vẫn tận dụng lợi thế của việc triển khai hành vi chuyên biệt của chúng Một lỗi lập trình phổ biến trong Java là vô tình làm quá tải một phương thức khi cố gắng ghi đè lên nó. Bất kỳ sự khác biệt nào về số lượng hoặc loại đối số (chữ ký của phương thức) sẽ tạo ra hai phương thức bị quá tải thay vì một phương thức bị ghi đè. Cú pháp chú thích mới trong Java 5. 0 cung cấp một cách để trình biên dịch trợ giúp vấn đề này. Chú thích, như chúng tôi sẽ mô tả trong Chương 7, cho phép chúng tôi thêm các điểm đánh dấu hoặc siêu dữ liệu đặc biệt vào mã nguồn mà trình biên dịch hoặc công cụ thời gian chạy có thể đọc được. Một trong những chú thích tiêu chuẩn mà Java định nghĩa được gọi là 25 và nó cho trình biên dịch biết rằng phương thức mà nó đánh dấu nhằm ghi đè lên một phương thức trong lớp cha. Sau đó, trình biên dịch sẽ cảnh báo nếu phương thức không khớp. Ví dụ: chúng ta có thể chỉ định rằng phương thức 82 của lớp 5 của chúng ta sẽ ghi đè một phương thức trong lớp cha như vậy 1 Các phương thức bị ghi đè và liên kết độngTrong phần trước, chúng tôi đã đề cập rằng các phương thức quá tải được trình biên dịch chọn tại thời điểm biên dịch. Mặt khác, các phương thức bị ghi đè được chọn động khi chạy. Ngay cả khi chúng ta tạo một thể hiện của một phân lớp mà mã của chúng ta chưa từng thấy trước đây (có lẽ là một lớp mới được tải qua mạng), thì bất kỳ phương thức ghi đè nào chứa trong đó đều được định vị và sử dụng trong thời gian chạy, thay thế những phương thức đã tồn tại khi chúng ta biên dịch mã lần cuối Ngược lại, nếu chúng ta tạo một lớp mới triển khai một phương thức quá tải bổ sung, cụ thể hơn và thay thế lớp đã biên dịch trong đường dẫn lớp của chúng ta bằng phương thức đó, thì mã của chúng ta sẽ tiếp tục sử dụng cách triển khai mà nó đã khám phá ban đầu. Tình trạng này sẽ tiếp tục cho đến khi chúng tôi biên dịch lại mã của mình cùng với lớp mới. Một hiệu ứng khác của điều này là việc truyền (i. e. , thông báo rõ ràng cho trình biên dịch coi một đối tượng là một trong các kiểu có thể gán của nó) ảnh hưởng đến việc lựa chọn các phương thức quá tải tại thời điểm biên dịch nhưng không ảnh hưởng đến các phương thức bị ghi đè Trong thực tế, những gì chúng tôi vừa mô tả không phải là điều bạn cần phải lo lắng thường xuyên, nhưng điều quan trọng là phải hiểu máy ảo làm gì và không làm gì trong thời gian chạy. Các phương thức tĩnh không thuộc về bất kỳ đối tượng nào; . Đó là lý do tại sao các phương thức tĩnh được gọi là "tĩnh"; Một phương thức tĩnh trong lớp cha có thể bị che khuất bởi một phương thức tĩnh khác trong lớp con, miễn là phương thức ban đầu không được khai báo là cuối cùng. Tuy nhiên, cả hai phương thức luôn có thể truy cập trực tiếp thông qua tên lớp tương ứng của chúng. Bạn không thể "ghi đè" một phương thức tĩnh bằng một phương thức thể hiện. Nói cách khác, bạn không thể có một phương thức tĩnh và một phương thức thể hiện có cùng chữ ký trong cùng một hệ thống phân cấp lớp phương pháp cuối cùng và hiệu suấtTrong các ngôn ngữ như C++, mặc định là các phương thức hoạt động giống như các biến ẩn, vì vậy bạn phải khai báo rõ ràng các phương thức bạn muốn là động (hoặc, như C++ gọi chúng là ảo). Trong Java, các phương thức thể hiện, theo mặc định, là động. Nhưng bạn có thể sử dụng công cụ sửa đổi 28 để tuyên bố rằng một phương thức thể hiện không thể bị ghi đè trong một lớp con và nó sẽ không bị ràng buộc động Chúng ta đã thấy 28 được sử dụng với các biến để biến chúng thành hằng số một cách hiệu quả. Khi được áp dụng cho một phương thức, 28 có nghĩa là việc triển khai của nó không đổi—không cho phép ghi đè. 28 cũng có thể được áp dụng cho toàn bộ lớp, điều đó có nghĩa là lớp không thể được phân lớp Trước đây, liên kết phương thức động đi kèm với một hình phạt hiệu suất đáng kể và một số người vẫn có xu hướng sử dụng công cụ sửa đổi 28 để bảo vệ chống lại điều này. Các hệ thống thời gian chạy Java hiện đại loại bỏ nhu cầu về loại tinh chỉnh này. Thời gian chạy định hình có thể xác định phương thức nào không bị ghi đè và "lạc quan" nội tuyến chúng, xử lý chúng như thể chúng là phương thức cuối cùng cho đến khi cần thiết phải làm khác. Theo quy định, bạn nên sử dụng từ khóa 28 khi nó phù hợp với cấu trúc chương trình của bạn, không phải để xem xét hiệu suất Trong một số phiên bản Java cũ hơn, trình biên dịch javac có thể được chạy với khóa -O, lệnh này yêu cầu trình biên dịch thực hiện một số tối ưu hóa nhất định, như nội tuyến, tĩnh. Hầu hết các tối ưu hóa này hiện được thực hiện trong thời gian chạy bởi các máy ảo thông minh hơn, do đó, các chuyển đổi như thế này thường không cần thiết Một loại tối ưu hóa khác cho phép bạn đưa mã gỡ lỗi vào nguồn Java của mình mà không bị phạt về kích thước hoặc hiệu suất. Mặc dù Java không có bộ tiền xử lý để kiểm soát rõ ràng nguồn nào được đưa vào, nhưng bạn có thể nhận được một số tác dụng tương tự bằng cách đặt một khối mã có điều kiện trên một hằng số (i. e. , 04 và 28) biến. Trình biên dịch Java đủ thông minh để loại bỏ mã này khi nó xác định rằng nó sẽ không được gọi. Ví dụ 8 Trong trường hợp này, trình biên dịch có thể nhận ra rằng điều kiện trên biến ________ 606 luôn là ________ 607 và phần thân của phương thức 08 sẽ được tối ưu hóa. Với trình biên dịch hiện đại, lệnh gọi phương thức thậm chí có thể được tối ưu hóa hoàn toàn Lưu ý rằng loại mã gỡ lỗi này hữu ích cho các mục đích như ghi nhật ký. Ngược lại với các xác nhận mà chúng tôi đã đề cập trong Chương 4, được cho là các kiểm tra có/không nhằm đảm bảo tính chính xác của logic chương trình của bạn, các khối mã có điều kiện này có thể thực hiện định dạng đắt tiền hoặc xử lý đầu ra khác hữu ích trong quá trình phát triển nhưng bạn Lựa chọn phương pháp xem xét lạiBây giờ bạn đã có một cảm giác tốt, trực quan về cách các phương thức được chọn từ nhóm các tên phương thức có khả năng bị quá tải và bị ghi đè của một lớp. Tuy nhiên, nếu bạn muốn biết thêm chi tiết, chúng tôi sẽ cung cấp ngay bây giờ Trong phần trước, chúng ta đã đưa ra một quy nạp quy nạp để giải quyết phương thức quá tải. Nó nói rằng một phương thức được coi là cụ thể hơn một phương thức khác nếu các đối số của nó có thể gán được cho các đối số của phương thức thứ hai. Bây giờ chúng ta có thể mở rộng quy tắc này để bao gồm việc giải quyết các phương thức bị ghi đè bằng cách thêm điều kiện sau. để cụ thể hơn một phương thức khác, loại lớp chứa phương thức này cũng phải được gán cho loại lớp chứa phương thức thứ hai Điều đó nghĩa là gì? . Bởi vì các loại lớp con có thể gán cho các loại lớp cha, nhưng không phải ngược lại, độ phân giải được đẩy theo cách mà chúng tôi mong đợi xuống chuỗi đối với các lớp con. Điều này bổ sung một cách hiệu quả chiều thứ hai cho tìm kiếm, trong đó độ phân giải được đẩy xuống cây thừa kế đối với các lớp được tinh chỉnh hơn và đồng thời hướng tới phương thức quá tải cụ thể nhất trong một lớp nhất định Ngoại lệ và phương pháp ghi đèMột phương thức ghi đè có thể thay đổi hành vi của một đối tượng, nhưng theo một số cách, nó vẫn phải thực hiện hợp đồng của phương thức ban đầu với người dùng. Cụ thể, một phương thức ghi đè phải tuân thủ mệnh đề 09 của phương thức ban đầu. Phương thức mới không thể ném các loại ngoại lệ được kiểm tra mới. Nó chỉ có thể tuyên bố rằng nó ném các loại ngoại lệ có thể gán cho những loại được ném bởi phương thức trong lớp cha; . Nếu phương thức mới không đưa ra bất kỳ ngoại lệ đã kiểm tra nào của bản gốc, thì nó không phải khai báo chúng và những người gọi phương thức thông qua lớp con không phải đề phòng chúng. (Bằng cách này, bạn có thể ghi đè lên một phương thức để “xử lý” các ngoại lệ cho người dùng. ) Vì vậy, phương thức mới có thể khai báo chính xác các ngoại lệ được kiểm tra giống như phương thức ban đầu hoặc nó có tùy chọn để tinh chỉnh các loại đó bằng cách tuyên bố rằng nó đưa ra các kiểu con cụ thể hơn so với phương thức đã ghi đè. Điều này không giống như việc chỉ nói rằng phương thức có thể đơn giản ném các kiểu con của các ngoại lệ đã khai báo của nó; . Phương pháp mới thực sự có thể xác định lại mệnh đề 09 của phương pháp cụ thể hơn. Kỹ thuật này được gọi là gõ hiệp biến của mệnh đề 09, có nghĩa là các loại ngoại lệ mà người dùng phải bảo vệ thay đổi để trở nên tinh tế hơn với loại phụ Hãy nhanh chóng xem lại mệnh đề 09 thực sự có nghĩa là gì. Nếu một phương thức tuyên bố rằng nó có thể ném ra một 13, thì điều đó thực sự nói rằng nó có thể ném ra các ngoại lệ kiểu 13 hoặc các kiểu con của nó. Ví dụ, 15 là một loại của 13. Một phương thức tuyên bố rằng nó có thể ném 13 thực sự có thể ném 15 hoặc bất kỳ kiểu con nào khác của 13 khi chạy 2 Khi chúng ta gọi phương thức này, trình biên dịch sẽ đảm bảo rằng chúng ta cho phép khả năng xảy ra bất kỳ loại 13 nào, bằng cách sử dụng khối 21 hoặc bằng cách ném ngoại lệ từ phương thức của chúng ta Khi chúng ta ghi đè một phương thức trong một lớp con, chúng ta có cơ hội viết lại mệnh đề 09 của phương thức một chút. Phương thức mới vẫn phải tương thích ngược với phương thức ban đầu, vì vậy mọi ngoại lệ được kiểm tra mà nó ném ra phải được gán cho những ngoại lệ được ném bởi phương thức bị ghi đè. Nhưng chúng ta có thể cụ thể hơn nếu muốn, tinh chỉnh loại ngoại lệ để phù hợp với hành vi của phương thức mới. Ví dụ 0 Trong mã này, 4 xác định rằng nó có thể ném một 24 từ phương thức 3 của nó. 26 là một lớp con của 4, vì vậy phương thức 3 của nó cũng phải có khả năng ném một 24. Tuy nhiên, phương thức 3 của 26 thực sự tuyên bố rằng nó ném ra một ngoại lệ cụ thể hơn. 32. Nó có thể làm điều này vì 32 là một kiểu con của 24. Nếu chúng ta đang làm việc trực tiếp với một loại 26, trình biên dịch sẽ cho phép chúng ta chỉ bắt được loại 32 và không yêu cầu chúng ta đề phòng loại chung chung hơn là 24 1 Mặt khác, nếu chúng tôi không quan tâm tại sao thực phẩm không ăn được, chúng tôi có thể tự do bảo vệ 24 chung chung hơn và coi nó như bất kỳ 4 nào khác Tóm lại, một phương thức ghi đè có thể tinh chỉnh không chỉ hành vi của phương thức cha mà còn cả loại ngoại lệ được kiểm tra mà nó đưa ra. Tiếp theo, chúng ta sẽ nói về các phương thức bị ghi đè thay đổi kiểu trả về của chúng theo cùng một cách Kiểu trả về và phương thức bị ghi đèĐể một phương thức đủ điều kiện là một phương thức được ghi đè trong một lớp con, phương thức đó phải có cùng số lượng và loại đối số. Nó phải có cùng “đầu vào” như nó vốn có. Như chúng ta đã thấy trong phần trước, các phương thức ghi đè có thể tinh chỉnh “đầu ra” của chúng ở một mức độ nào đó. Cụ thể, họ có thể thu hẹp mệnh đề 09 của mình bằng cách tuyên bố rằng họ ném các kiểu con của các kiểu ngoại lệ của phương thức ban đầu. Còn “đầu ra” chính của một phương pháp thì sao? Điều này có nghĩa là khi bạn ghi đè một phương thức, bạn có thể thay đổi kiểu trả về thành kiểu con của kiểu trả về của phương thức ban đầu. Ví dụ: nếu lớp 4 của chúng tôi có một phương thức xuất xưởng có tên là 42 tạo ra một thể hiện của 4, thì lớp 1 của chúng tôi có thể tinh chỉnh kiểu trả về thành 1 2 Như chúng ta sẽ thấy ở phần sau, kỹ thuật viết mã này rất hữu ích vì nó loại bỏ một số thao tác truyền đối tượng trong thời gian chạy. Tài liệu tham khảo đặc biệt. cái này và siêuCác tham chiếu đặc biệt 46 và 84 cho phép bạn lần lượt tham chiếu đến các thành viên của thể hiện đối tượng hiện tại hoặc các thành viên của lớp cha. Chúng ta đã thấy 46 được sử dụng ở những nơi khác để truyền tham chiếu đến đối tượng hiện tại và để tham chiếu đến các biến thể hiện bị che khuất. Tham chiếu 84 cũng làm như vậy đối với phụ huynh của một lớp. Bạn có thể sử dụng nó để chỉ các thành viên của một siêu lớp đã bị che khuất hoặc bị ghi đè. Khả năng gọi phương thức ban đầu của lớp cha cho phép chúng ta sử dụng nó như một phần của phương thức mới, ủy quyền cho hành vi của nó trước hoặc sau khi chúng ta thực hiện công việc bổ sung 3 Trong ví dụ này, lớp 26 của chúng ta ghi đè phương thức ________ 651 để trước tiên thực hiện một số kiểm tra trên đối tượng ________ 652. Sau khi thực hiện công việc của mình, nó sử dụng 53 để gọi triển khai (nếu không sẽ bị ghi đè và không thể truy cập được) của 3 trong lớp cha của nó 84 nhắc tìm kiếm phương thức hoặc biến bắt đầu trong phạm vi của lớp cha trực tiếp thay vì lớp hiện tại. Phương thức hoặc biến được kế thừa được tìm thấy có thể nằm trong lớp cha trực tiếp hoặc một lớp tiếp theo trên cây. Việc sử dụng tham chiếu 84 khi được áp dụng cho các phương thức được ghi đè của lớp cha là đặc biệt; . Không có 84, sẽ không có cách nào để truy cập các phương thức bị ghi đè Một diễn viên yêu cầu trình biên dịch thay đổi loại rõ ràng của một tham chiếu đối tượng. Công dụng chính của ép kiểu là khi một đối tượng tạm thời được gán cho một kiểu tổng quát hơn. Ví dụ: nếu một 58 được gán cho một biến loại 59, để sử dụng lại nó như một 58, chúng ta phải thực hiện ép kiểu để lấy lại nó. Trình biên dịch chỉ nhận ra các loại biến được khai báo và không biết rằng chúng ta đã thực sự đặt một 58 vào đó. Trong Java, các diễn viên được kiểm tra cả khi biên dịch và khi chạy để đảm bảo rằng chúng hợp pháp. Tại thời điểm biên dịch, trình biên dịch Java sẽ ngăn bạn cố gắng thực hiện một phép ép kiểu không thể hoạt động (chẳng hạn như chuyển trực tiếp một 62 thành một 58). Và trong thời gian chạy, Java sẽ kiểm tra xem các phôi có hợp lý không (chẳng hạn như 59 đến 58 của chúng tôi) có thực sự chính xác đối với các đối tượng thực có liên quan hay không Cố gắng truyền một đối tượng sang một loại không tương thích trong thời gian chạy sẽ dẫn đến ____666 67 68. Chỉ các phép truyền giữa các đối tượng trong cùng một hệ thống phân cấp thừa kế (và, như chúng ta sẽ thấy sau, với các giao diện phù hợp) là hợp pháp trong Java và vượt qua sự giám sát kỹ lưỡng của trình biên dịch và hệ thống thời gian chạy. Diễn viên trong Java chỉ ảnh hưởng đến việc xử lý các tham chiếu; . Đây là một quy tắc quan trọng cần ghi nhớ. Bạn không bao giờ thay đổi đối tượng được trỏ tới bởi một tham chiếu bằng cách ép kiểu nó; Có thể sử dụng phép truyền để thu hẹp hoặc hạ thấp loại tham chiếu—để làm cho nó cụ thể hơn. Thông thường, chúng tôi sẽ làm điều này khi chúng tôi phải truy xuất một đối tượng từ một loại bộ sưu tập tổng quát hơn hoặc khi nó đã được sử dụng trước đó như một loại ít dẫn xuất hơn. (Ví dụ nguyên mẫu đang sử dụng một đối tượng trong bộ sưu tập, như chúng ta sẽ thấy trong Chương 11. ) Tiếp tục với ví dụ về 5 của chúng ta 4 Chúng ta không thể gán lại tham chiếu trong 48 cho biến 46 mặc dù chúng ta biết rằng nó chứa một thể hiện của một 5 (Simon). Chúng ta phải thực hiện ép kiểu được chỉ định để thu hẹp tham chiếu. Lưu ý rằng một phép gán ẩn đã được thực hiện khi chúng tôi thực hiện theo cách khác để mở rộng tham chiếu 46 thành loại 4 trong lần gán đầu tiên. Trong trường hợp này, một diễn viên rõ ràng sẽ hợp pháp nhưng không cần thiết Tất cả điều này có nghĩa là bạn không thể nói dối hoặc đoán về một đối tượng. Nếu bạn có một đối tượng 5, bạn có thể sử dụng nó như một 4 hoặc thậm chí là ________ 659 vì tất cả các lớp Java đều là lớp con của ________ 659. Nhưng nếu bạn có một 59 mà bạn nghĩ là một 5, thì bạn phải thực hiện ép diễn viên để đưa nó trở lại một 4 hoặc một 5. Nếu bạn không chắc chắn liệu 59 là một 5 hay một 85 trong thời gian chạy, bạn có thể kiểm tra nó với 86 trước khi thực hiện ép kiểu. Nếu bạn không kiểm tra và bạn truyền sai, hệ thống thời gian chạy sẽ đưa ra một lỗi 66 67 68 5 Như chúng tôi đã đề cập trước đó, việc ép kiểu có thể ảnh hưởng đến việc lựa chọn các mục thời gian biên dịch, chẳng hạn như các biến và các phương thức quá tải, nhưng không ảnh hưởng đến việc lựa chọn các phương thức bị ghi đè. Hình 6-4 cho thấy sự khác biệt. Như được hiển thị trong nửa trên của sơ đồ, việc chuyển tham chiếu 46 sang loại 4 (mở rộng nó) ảnh hưởng đến việc lựa chọn biến bóng mờ 2 bên trong nó. Tuy nhiên, như nửa dưới của sơ đồ chỉ ra, việc ép kiểu không ảnh hưởng đến việc lựa chọn phương thức bị ghi đè 82 Hình 6-4. Đúc và lựa chọn các phương pháp và biến Truyền trong Java là điều mà các lập trình viên cố gắng tránh. Điều này không chỉ bởi vì nó chỉ ra một điểm yếu trong cách gõ tĩnh của mã, mà bởi vì các phép truyền cũng có thể đơn giản là tẻ nhạt khi sử dụng và làm cho mã khó đọc hơn. Thật không may, rất nhiều mã được viết bằng Java trong quá khứ không có lựa chọn nào khác ngoài việc dựa vào ép kiểu để nó có thể hoạt động với bất kỳ loại đối tượng nào mà người dùng yêu cầu. java5. 0 đã giới thiệu một tính năng ngôn ngữ mới, generics, một phần để giải quyết vấn đề này. Generics cho phép người dùng "gõ" mã Java cho một loại đối tượng cụ thể, loại bỏ nhu cầu truyền trong nhiều tình huống. Chúng ta sẽ đề cập chi tiết về khái quát trong Chương 8 và xem cách chúng giảm nhu cầu truyền trong hầu hết mã Java Sử dụng Superclass ConstructorTrước đây khi chúng ta nói về các hàm tạo, chúng ta đã thảo luận về cách câu lệnh đặc biệt 94 gọi một hàm tạo bị quá tải khi nhập vào một hàm tạo khác. Tương tự, câu lệnh 95 gọi hàm tạo của một lớp cha một cách rõ ràng. Tất nhiên, chúng ta cũng đã nói về cách Java thực hiện một chuỗi lệnh gọi hàm tạo bao gồm hàm tạo của siêu lớp, vậy tại sao lại sử dụng rõ ràng 95? . Nếu chúng ta muốn gọi một hàm tạo của lớp bậc trên nhận các đối số, chúng ta phải thực hiện điều đó một cách rõ ràng bằng cách sử dụng 95 Nếu chúng ta định gọi một hàm tạo của lớp bậc trên với 95, thì đó phải là câu lệnh đầu tiên của hàm tạo của chúng ta, giống như 94 phải là lệnh gọi đầu tiên chúng ta thực hiện trong một hàm tạo quá tải. Đây là một ví dụ đơn giản 6 Trong ví dụ này, chúng tôi sử dụng 95 để tận dụng lợi thế của việc triển khai hàm tạo của lớp cha và tránh sao chép mã để thiết lập đối tượng dựa trên tên của nó. Trên thực tế, vì lớp 01 không định nghĩa hàm tạo mặc định (không có đối số), nên chúng tôi không có lựa chọn nào khác ngoài việc gọi 95 một cách rõ ràng. Nếu không, trình biên dịch sẽ phàn nàn rằng nó không thể tìm thấy hàm tạo mặc định thích hợp để gọi. Nói cách khác, nếu bạn phân lớp một lớp có tất cả các hàm tạo đều nhận đối số, thì bạn phải gọi một trong các hàm tạo của lớp cha một cách rõ ràng từ ít nhất một trong các hàm tạo của lớp con của bạn Các biến thể hiện của lớp được khởi tạo khi trả về từ hàm tạo của lớp bậc trên, cho dù đó là do lệnh gọi rõ ràng tới 95 hay lệnh gọi ẩn tới hàm tạo mặc định của lớp bậc trên tiết lộ đầy đủ. Constructor và khởi tạoBây giờ chúng ta có thể kể toàn bộ câu chuyện về cách các hàm tạo được liên kết với nhau và khi khởi tạo biến thể hiện xảy ra. Quy tắc có ba phần và được áp dụng lặp lại cho mỗi hàm tạo liên tiếp được gọi
Các phương thức và lớp trừu tượngMột phương thức trong Java có thể được khai báo bằng công cụ sửa đổi 09 để chỉ ra rằng nó chỉ là một nguyên mẫu. Một phương thức trừu tượng không có phần thân; . Bạn không thể trực tiếp sử dụng một lớp có chứa một phương thức trừu tượng; 7 Trong Java, một lớp chứa một hoặc nhiều phương thức trừu tượng phải được khai báo rõ ràng là một lớp trừu tượng, đồng thời sử dụng công cụ sửa đổi 09 8 Một lớp trừu tượng có thể chứa các phương thức phi trừu tượng khác và các khai báo biến thông thường, nhưng nó không thể được khởi tạo. Để được sử dụng, nó phải được phân lớp và các phương thức trừu tượng của nó phải được "ghi đè" bằng các phương thức triển khai phần thân. Không phải tất cả các phương thức trừu tượng đều phải được triển khai trong một lớp con duy nhất, nhưng một lớp con không ghi đè tất cả các phương thức trừu tượng của lớp cha của nó bằng các triển khai cụ thể, thực tế cũng phải được khai báo 09 9 Các lớp trừu tượng cung cấp một khung cho các lớp sẽ được “điền vào” bởi người triển khai. Ví dụ, lớp 12 có một phương thức trừu tượng duy nhất có tên là 13. Các lớp con khác nhau của 14 triển khai 13 theo cách riêng của chúng để đọc từ các nguồn riêng của chúng. Tuy nhiên, phần còn lại của lớp 14 cung cấp chức năng mở rộng được xây dựng trên phương thức 13 đơn giản. Lớp con của 14 kế thừa các phương thức phi trừu tượng này để cung cấp chức năng dựa trên phương thức 13 đơn giản mà lớp con thực hiện một quizlet lớp trừu tượng là gì?Một lớp trừu tượng là một lớp không thể khởi tạo . Nó được sử dụng bằng cách tạo một lớp con kế thừa có thể được khởi tạo.
Khi một phương thức trong một lớp con có cùng chữ ký với một phương thức trong lớp cha thì nó?Giải thích. Khi một phương thức trong một lớp con có cùng tên và kiểu ký hiệu như một phương thức trong lớp cha, thì phương thức trong lớp con sẽ ghi đè phương thức trong lớp cha .
Điều gì là cần thiết cho một phương thức giao diện có phần thân?Điều gì là cần thiết cho một phương thức giao diện có phần thân? . The method header must begin with the key word default.
Lớp con kế thừa gì từ lớp cha?Một lớp con kế thừa tất cả các thành viên (trường, phương thức và lớp lồng nhau) từ lớp cha của nó. Các hàm tạo không phải là thành viên, vì vậy chúng không được kế thừa bởi các lớp con, nhưng hàm tạo của lớp cha có thể được gọi từ lớp con. |