Lớp cuối cùng có nghĩa là gì trong PHP?
Hợp đồng rõ ràng, tác dụng phụ riêng biệt, khả năng kiểm tra, độ phức tạp và tải nhận thức thấp, tính linh hoạt của mã và sự tự tin vào bản thân Show
Động lựcGiảm khả năng hiển thị phạm vi xuống mức tối thiểuKhi bạn nhìn thấy một tiền tố lớp với cuối cùng, bạn sẽ ngăn một lớp cụ thể được mở rộng bởi bất kỳ lớp nào khác, điều này không chỉ làm cho nó dễ đọc hơn mà còn đảm bảo rằng phạm vi logic mà bạn đang ở bị giới hạn ở lớp cụ thể đó Khuyến khích tâm lý “sáng tác hơn kế thừa”Nguyên tắc Đóng-Mở phát biểu. mở để mở rộng nhưng đóng để sửa đổi Nếu vì bất kỳ lý do gì, một lý do tốt mà bạn hoàn toàn nên biết, bạn quyết định tạo một tài sản thừa kế ở đó, thì chỉ cần bỏ từ khóa cuối cùng và bạn đã sẵn sàng để tiếp tục Khi bạn “theo mặc định” không thể mở rộng từ một lớp (vì nó là lớp cuối cùng), bạn sẽ tự giúp mình bằng cách nghĩ đến việc sử dụng thành phần thay vì kế thừa Tại sao lớp học này không phải là cuối cùng?Nếu chúng ta đặt mục tiêu tổng hợp hơn là kế thừa, thì chúng ta nên cố gắng tránh kế thừa càng nhiều càng tốt và chỉ sử dụng nó khi thực sự cần thiết. Kế thừa thường bị lạm dụng trong OOP quan niệm sai lầmKhi chúng tôi dạy OOP lần đầu tiên, chúng tôi thường giới thiệu ví dụ kế thừa cổ điển Tuy nhiên, khi Alan Kay tạo ra Smalltalk, tính kế thừa chưa bao giờ là khái niệm chính của nó. Khái niệm chính là gửi tin nhắn, nghĩa là bạn có thể gửi tin nhắn đến các đối tượng và chúng đóng gói dữ liệu và logic trong đó, đồng thời bạn có thể thay đổi hành vi của chúng bằng cách sử dụng các đối tượng khác nhau, thực chất là thành phần. Nhưng khái niệm kế thừa quá phổ biến cuối cùng làm lu mờ thành phần Những lợi ích
Thành phần trên thừa kếNếu bạn cảm thấy cần phải cấu hình lại một đối tượng, thay đổi các phần của thuật toán hoặc viết lại một phần của quá trình triển khai, hãy xem xét việc tạo một lớp mới thay vì ghi đè lên một lớp hiện có. Nếu bạn cần biểu diễn một hệ thống phân cấp của các lớp, trong đó các lớp con là lớp thay thế thích hợp cho lớp cha của chúng. Đây sẽ là tình huống cổ điển mà bạn vẫn có thể xem xét thừa kế. Tuy nhiên, kết quả thậm chí có thể tốt hơn nếu bạn không kế thừa từ các lớp cha cụ thể mà từ các giao diện trừu tượng Gần đây tôi đã viết về thời điểm thêm giao diện vào một lớp. Sau khi giải thích những lý do chính đáng để thêm giao diện, tôi khẳng định rằng nếu không có lý do nào trong số đó áp dụng cho trường hợp của bạn, thì bạn chỉ nên sử dụng một lớp và tuyên bố nó là "cuối cùng"
Một minh họa về cú pháp
Trong vài năm nay, tôi đã sử dụng từ khóa Tuy nhiên, tôi cũng nhớ sự phản đối ban đầu của mình đối với việc thêm Thay thế. lớp học không cuối cùngBỏ qua từ khóa Bạn là người thiết kế ban đầu của lớp và bạn đã nghĩ đến một trường hợp sử dụng cụ thể khi tạo lớp đó. Sử dụng lớp cho mục đích khác bằng cách ghi đè một phần hành vi của lớp có thể gây nguy hiểm cho tính toàn vẹn của lớp. Trạng thái của đối tượng mở rộng có thể trở nên khó đoán hoặc không phù hợp với trạng thái của đối tượng ban đầu. Hoặc hành vi có thể thay đổi theo cách mà lớp con không còn được coi là sự thay thế thích hợp cho lớp cơ sở Hơn nữa, nhà phát triển tạo một lớp con của lớp bạn để ghi đè hành vi của nó, có thể không cần tất cả các phần bên trong của lớp cha. Tuy nhiên, nó kế thừa những phần bên trong đó (cấu trúc dữ liệu, phương thức riêng tư) và sẽ sớm đi đến điểm mà nó phải hoạt động xung quanh chúng Về sự phát triển trong tương lai, có một vấn đề khác. lớp hiện đã được phân lớp, vẫn có một cuộc sống riêng. Khách hàng của nó có thể có những nhu cầu khác nhau theo thời gian, vì vậy những thay đổi sẽ được thực hiện đối với nó. Những thay đổi này cũng có thể ảnh hưởng đến các lớp con, vì chúng có thể dựa vào một chi tiết triển khai cụ thể của lớp cha. Khi chi tiết này thay đổi, phân lớp sẽ bị phá vỡ Từ tất cả những vấn đề này, chúng tôi phải kết luận rằng bằng cách cho phép phân lớp, chúng tôi sẽ dẫn đến một tình huống không mong muốn. Tương lai của lớp con và lớp cha sẽ trở nên gắn bó với nhau. Tái cấu trúc lớp cha sẽ khá khó khăn, bởi vì ai biết lớp nào đang dựa vào một chi tiết triển khai cụ thể. Và vì lớp con không cần tất cả dữ liệu và hành vi của lớp cha, nên chúng có thể hành động như thể chúng là cùng một thứ, nhưng trên thực tế, chúng không phải vậy. Thay thế tốt hơn ghi đèVì vậy, việc thay đổi hành vi của một lớp không nên được thực hiện bằng cách phân lớp lớp đó và ghi đè các phương thức. Nhưng chúng ta có thể làm gì khác? . Hoặc là do lớp được sử dụng và dựa vào nơi khác trong dự án hoặc về mặt vật lý, nó không phải là một tùy chọn để sửa đổi mã của nó vì nó là một phần của gói nhà cung cấp Tôi thậm chí muốn nói rằng thay đổi mã không phải là cách ưa thích để thay đổi hành vi ngay từ đầu. Nếu bạn có thể, hãy thay đổi hành vi của một đối tượng bằng cách cấu hình lại nó, nghĩa là bằng cách tráo đổi các đối số của hàm tạo, bạn nên làm điều đó Điều này nhắc chúng ta về nguyên tắc Đảo ngược phụ thuộc, theo đó chúng ta nên phụ thuộc vào sự trừu tượng và nguyên tắc Mở/đóng, giúp chúng ta thiết kế các đối tượng có thể cấu hình lại mà không cần chạm vào mã của nó Còn mẫu Phương thức mẫu thì sao?Có một cách tiếp cận khác để thay đổi hành vi của một lớp. Đó là một mẫu hành vi được mô tả trong "Mẫu thiết kế" cổ điển. Các yếu tố của phần mềm hướng đối tượng tái sử dụng". Mẫu được gọi là "Phương thức mẫu"
Giải pháp này tốt hơn một chút so với việc cho phép các lớp con ghi đè hành vi của lớp cha, vì nó giới hạn những gì có thể thay đổi. Nó làm cho lớp cha trở nên vô dụng bằng cách đánh dấu nó là 0 và 1. đó là cả hai phần nhỏ hơn của thuật toán tổng thể. Symfony sẽ không thể đoán được những triển khai này, vì chúng dành riêng cho dự án
Nó thực sự rất hay, tuy nhiên, không có gì ở đây không thể giải quyết bằng thành phần thay vì kế thừa. Một giải pháp tương đương sẽ là
Theo lý do từ "Khi nào nên thêm một giao diện vào một lớp", chúng ta thậm chí có thể xem xét lại sự hiện diện của một 2 trong ví dụ trên. Nếu tất cả việc bỏ phiếu được thực hiện theo cùng một cách, nghĩa là thuật toán bỏ phiếu giống nhau trong mọi tình huống, chúng tôi thực sự không muốn người dùng viết triển khai của riêng họ về 2. Vì vậy, chúng tôi cũng có thể chỉ cung cấp lớp Voter chứ không phải giao diện (tôi thực sự không chắc đó có phải là trường hợp của thành phần Bảo mật Symfony hay không, nhưng đó là một lựa chọn thiết kế tốt để xem xét trong các dự án của riêng bạn)Giải pháp đề xuất không liên quan đến thừa kế nữa. Nó để lại phần bên trong của tất cả các lớp liên quan cho chính họ. Nghĩa là, tất cả các lớp này đều có thể là Thành phần trên thừa kếBạn có thể đã nghe cụm từ "Thành phần hơn thừa kế" trước đây; . Trong hầu hết các trường hợp, bạn nên ưu tiên giải pháp liên quan đến thành phần hơn là giải pháp liên quan đến kế thừa. Cụ thể hơn, nếu bạn cảm thấy cần phải cấu hình lại một đối tượng, thay đổi các phần của thuật toán, viết lại một phần của quá trình triển khai, hãy xem xét việc tạo một lớp mới thay vì ghi đè lên một lớp hiện có. Nếu bạn cần biểu diễn một hệ thống phân cấp của các lớp, trong đó các lớp con là lớp thay thế thích hợp cho lớp cha của chúng, thì đây sẽ là tình huống kinh điển mà bạn vẫn có thể xem xét tính kế thừa. Tuy nhiên, kết quả vẫn có thể tốt hơn nếu bạn không kế thừa từ các lớp cha cụ thể mà từ các giao diện trừu tượng. Tuy nhiên, điều này rất khó để hiểu đúng (cá nhân tôi rất tiếc về phần lớn công việc trước đây của tôi liên quan đến thừa kế), vì vậy nếu có thể, bạn vẫn nên bố cục hơn Tiện ích mở rộng phải là một trường hợp sử dụng riêng biệtVới tư cách là người thiết kế lớp, bạn tạo lớp theo cách sao cho nó cung cấp một số điều hữu ích mà người dùng có thể thực hiện với lớp đó. Ví dụ, họ có thể
"Cấu hình lại nó để thay đổi một phần hành vi của nó" cũng nên có trong danh sách này, dưới dạng một mục riêng biệt. Và do đó, nên "cho phép nó được mở rộng để ghi đè lên một phần hành vi của nó". Đó phải là một quyết định có chủ ý để cho phép người dùng làm điều đó với lớp của bạn. Việc cho phép một lớp được mở rộng có (thường hạn chế) hậu quả đối với thiết kế của nó và tương lai của nó. Vì vậy, ít nhất bạn không nên cho phép nó theo mặc định "Cuối cùng" đẩy mọi người đi đúng hướngVì vậy, nếu cho phép người dùng phân lớp một lớp không phải là tiêu chuẩn, thì việc không cho phép nó phải là. Nói cách khác. thêm "Bạn luôn có thể xóa bản cuối cùng nếu muốn"Tôi thường nghe một lập luận về việc sử dụng "Công cụ mô phỏng của tôi không hoạt động với các lớp cuối cùng"Một phản đối đối với các lớp học cuối cùng mà tôi thường nghe là. "Tôi thích những gì bạn nói, nhưng công cụ chế giễu của tôi không hoạt động với các lớp cuối cùng". Thật vậy, hầu hết không. Nó có ý nghĩa, bởi vì thử nghiệm nhân đôi mà một công cụ như vậy tạo ra thường trông giống như thế này
Thật không may, nhưng các công cụ không thể đổ lỗi. Họ sẽ phải thực hiện một số việc lén lút như móc vào trình tải lớp để biến lớp không phải là cuối cùng (thực tế, điều đó hoàn toàn có thể thực hiện được). Nhưng họ thì không, vì vậy sự thật bị tát vào mặt chúng ta. Tất cả những gì công cụ nói là không thể mở rộng lớp cuối cùng - không có vấn đề gì về lỗi nghiêm trọng đó. Thay vào đó, bất cứ khi nào chúng tôi cảm thấy cần phải thay thế một lớp cuối cùng bằng một bài kiểm tra kép, chúng tôi nên xem xét hai tùy chọn
Tùy chọn 1 thường hữu ích khi bạn đang cố chế nhạo những thứ như thực thể và đối tượng giá trị. Chỉ cần không làm điều đó Phương án 2 nên được áp dụng trong hầu hết các trường hợp khác. Khi lớp lẽ ra phải có một giao diện, hãy thêm một giao diện và thay vào đó hãy tạo một thử nghiệm kép cho giao diện Phần kết luậnTóm lại là. làm cho các lớp học của bạn lớp học cuối cùng có nghĩa là gì?Lớp cuối cùng là lớp được khai báo với từ khóa final . Lớp con không thể kế thừa lớp cuối cùng hoặc lớp cuối cùng không thể được kế thừa bởi bất kỳ lớp con nào. Vì vậy, chúng ta có thể hạn chế kế thừa lớp bằng cách sử dụng lớp cuối cùng.
Sự khác biệt giữa lớp học cuối cùng và lớp học thông thường là gì?Mục đích chính của việc sử dụng lớp cuối cùng là để ngăn không cho lớp đó được kế thừa (i. e. ) nếu một lớp được đánh dấu là cuối cùng, thì không lớp nào khác có thể kế thừa bất kỳ thuộc tính hoặc phương thức nào từ lớp cuối cùng . Nếu lớp cuối cùng được mở rộng, Java sẽ báo lỗi thời gian biên dịch.
Làm cách nào để kế thừa lớp cuối cùng trong PHP?Từ khóa cuối cùng ¶
. Nếu bản thân lớp đang được định nghĩa cuối cùng thì nó không thể được mở rộng. prefixing the definition with final . If the class itself is being defined final then it cannot be extended.
Tĩnh và cuối cùng trong PHP là gì?cuối cùng static khai báo một phương thức tĩnh (có thể được gọi mà không cần phiên bản của lớp) và cuối cùng (không thể bị lớp con ghi đè). static alone can be used to define a class-scoped variable, which isn't constant (but variables can't be final ). |