Python tạo cá thể lớp con từ cá thể siêu lớp
Về cốt lõi, Python là một ngôn ngữ OOP theo thiết kế. Nó có mọi thứ được triển khai dưới dạng đối tượng, gói, mô-đun, lớp, chức năng và chắc chắn là đối tượng thể hiện của lớp. Khi chúng tôi xây dựng các ứng dụng của mình, chúng tôi thường phải tạo các lớp tùy chỉnh để kết hợp các chức năng và dữ liệu liên quan lại với nhau — một cách tiếp cận OOP điển hình để giải quyết các vấn đề lập trình Show
Với sự phát triển của dự án trong phạm vi của nó, gần như không thể tránh khỏi việc bạn cần tạo các lớp con. Trong bài viết này, tôi muốn nhấn mạnh một số tính năng/cân nhắc mà bạn nên lưu ý khi xác định lớp con của mình. Xin lưu ý rằng tôi không sử dụng bất kỳ giả định nào liên quan đến trình độ kiến thức của bạn, vì vậy tôi có thể trình bày những nội dung rất cơ bản, nhưng những điểm chính này phải đủ tốt để bạn bắt đầu phân lớp Không chần chừ nữa, hãy bắt đầu nào 1. Tại sao chúng ta phân lớp? Điều đầu tiên, tại sao chúng ta phải tạo một lớp con? . Nói cách khác, khi chúng ta cần tạo các lớp con, chúng ta cần tạo ít nhất hai lớp con có chung một lớp cha. Nếu bạn không thấy điều đó, tôi không nghĩ bạn nên phân lớp Đoạn trên dường như nói về “hậu quả” — những thứ mà bạn kiểm tra sau khi đã tạo một lớp con. Nếu chúng ta lùi lại, chúng ta nên tự hỏi khi nào nên tạo các lớp con Giả sử rằng chúng ta đang thực hiện một dự án để tạo một ứng dụng cho mọi người sử dụng trong trường học. Chúng tôi biết rằng có hai loại người trong một trường học. học sinh và giáo viên. Vì vậy, chúng tôi tạo hai lớp quản lý dữ liệu cho từng danh mục. Một số cấu trúc trần của hai lớp này được hiển thị bên dưới Học sinh và Giáo viên (Lớp riêng biệt)Trong lớp student = Student("David", 20020)8, chúng tôi định nghĩa ba thuộc tính. student = Student("David", 20020)9, student = Student("David", 20020)0, và student = Student("David", 20020)1 và ba phương thức thể hiện. student = Student("David", 20020)0, student = Student("David", 20020)1 và student = Student("David", 20020)2. Trong lớp Teacher, chúng ta cũng định nghĩa ba thuộc tính. student = Student("David", 20020)9, student = Student("David", 20020)4, và student = Student("David", 20020)5, và ba phương thức thể hiện. student = Student("David", 20020)6, student = Student("David", 20020)1 và student = Student("David", 20020)2. Như bạn có thể thấy, hai lớp này chia sẻ các thuộc tính và phương thức tương tự nhau, và hình dưới đây cung cấp một bản tóm tắt trực quan Trong hình trên, chúng ta lưu ý phần lớn hai lớp này giống nhau như thế nào và sự giống nhau giữa nhiều lớp này là cơ sở để tạo ra một lớp cha Xin lưu ý rằng trong thực tế, các lớp học của bạn có thể phức tạp hơn những gì thể hiện trong hình. Nhưng điều quan trọng nhất cần lưu ý là khi hai hoặc nhiều lớp chia sẻ các chức năng chồng chéo, bạn nên xem xét việc tạo một lớp cha, lớp cha này sẽ xử lý các chức năng được chia sẻ này
2. Bộ xương thiết yếu của siêu lớp Bây giờ chúng ta đã biết lý do để tạo ra một lớp cha. Câu hỏi rõ ràng đầu tiên là chúng ta nên đặt tên cho lớp cha của mình là gì. Trong hầu hết các trường hợp, chúng ta chỉ cần lấy góc từ quan điểm danh nghĩa hoặc ngữ nghĩa. Vì cả học sinh và giáo viên đều thuộc khái niệm lớn hơn về “người”, chúng ta chỉ có thể đặt tên cho siêu lớp là student = Student("David", 20020)9 Trong lớp student = Student("David", 20020)9, chúng tôi hy vọng rằng lớp cha sẽ nắm bắt các chức năng được chia sẻ cho các lớp con. student = Student("David", 20020)8 và student = Student("David", 20020)02. Do đó, để giúp chúng tôi xác định cấu trúc của lớp cha, sẽ rất hữu ích nếu bạn có thể tạo một sơ đồ hiển thị cho bạn bộ khung thiết yếu của lớp cha, cũng như của các lớp con mà không chỉ định bất kỳ chi tiết triển khai nào vào lúc này Như bạn có thể thấy, chúng tôi đặt các thuộc tính được chia sẻ. student = Student("David", 20020)9 và student = Student("David", 20020)04 (kết hợp student = Student("David", 20020)0 và student = Student("David", 20020)4) và các phương thức dùng chung. student = Student("David", 20020)1 và student = Student("David", 20020)2 trong lớp cha. Rõ ràng, các thuộc tính và phương thức riêng biệt dự kiến sẽ được triển khai trong các lớp con. student = Student("David", 20020)8 và student = Student("David", 20020)02 3. Tạo siêu lớp Trong phần trước, chúng ta có một kế hoạch liên quan đến sự sắp xếp tương đối của các chức năng được chia sẻ và riêng biệt giữa lớp cha và lớp con. Bây giờ, đã đến lúc bắt đầu viết mã cho lớp cha. Hãy xem đoạn mã dưới đây trước khi tôi bắt đầu giải thích Siêu lớp — NgườiTrong phương thức khởi tạo của lớp cha, chúng tôi chỉ bao gồm hai thuộc tính được chia sẻ bởi student = Student("David", 20020)8 và student = Student("David", 20020)02. student = Student("David", 20020)9 và student = Student("David", 20020)04. Trong khi đó, chúng tôi chỉ định nghĩa các phương thức được chia sẻ bởi các lớp con. student = Student("David", 20020)1 và student = Student("David", 20020)2
4. Tái cấu trúc các lớp con Sau khi chúng tôi bố trí triển khai thiết yếu của lớp cha student = Student("David", 20020)9, bây giờ là bước quay lại để cấu trúc lại các lớp student = Student("David", 20020)8 và student = Student("David", 20020)02 ban đầu của chúng tôi, vì bây giờ chúng sẽ kế thừa từ lớp student = Student("David", 20020)9 theo kế hoạch Định nghĩa một lớp conVới một siêu lớp hiện có, việc xác định một siêu lớp bao gồm cú pháp sau. student = Student("David", 20020)31. Áp dụng mẫu này ta được các đầu sau cho lớp student = Student("David", 20020)8 và lớp student = Student("David", 20020)02 student = Student("David", 20020)5 Kế thừa các thuộc tính và phương thứcHiện tại, chúng tôi không có bất kỳ mã nào trong nội dung của Học sinh và Giáo viên. Nhưng phân lớp cho phép lớp con kế thừa tất cả các thuộc tính và phương thức mà chúng ta đã định nghĩa trong lớp cha. Đó chính xác là lợi thế chính của phân lớp - các chức năng được chia sẻ có sẵn ngay lập tức cho các lớp con của lớp cha mà không cần phân lớp làm bất cứ điều gì. Hãy quan sát hiệu ứng này student = Student("David", 20020) Như bạn có thể thấy, chúng ta có thể tạo một thể hiện của lớp student = Student("David", 20020)8 bằng cách sử dụng hàm tạo được định nghĩa trong lớp cha và gọi phương thức student = Student("David", 20020)1 trong thể hiện này. Chúng ta có thể làm những điều tương tự với lớp student = Student("David", 20020)02 Ghi đè phương thức khởi tạoTrong nhiều trường hợp, chúng ta cần ghi đè phương thức khởi tạo trong lớp con, bởi vì chúng ta có thể có nhiều thuộc tính hơn những gì được định nghĩa trong lớp cha. Trước tiên hãy xem mã, chỉ sử dụng lớp student = Student("David", 20020)8 làm ví dụ và bạn có thể áp dụng các kỹ thuật tương tự cho lớp student = Student("David", 20020)02 student = Student("David", 20020)0 Trong phương thức student = Student("David", 20020)39, chúng ta có thể khởi tạo thuộc tính grade như chúng ta thường làm trong một lớp tùy chỉnh. Bên cạnh đó, điều quan trọng nhất cần quan sát là chúng ta sử dụng phương thức khởi tạo của siêu lớp bằng cách gọi student = Student("David", 20020)20. Việc gọi student = Student("David", 20020)21 tạo một đối tượng proxy tham chiếu đến siêu lớp ( student = Student("David", 20020)9) sao cho chúng ta có thể sử dụng phương thức khởi tạo của siêu lớp bằng cách gửi student = Student("David", 20020)9 và student = Student("David", 20020)04. Bạn có thể biết điều đó, nhưng cũng giống như một lời nhắc nhở thân thiện rằng việc gọi student = Student("David", 20020)39 không nhận được bất kỳ giá trị trả về nào và nó chỉ đơn giản là thiết lập các thuộc tính khởi tạo Ghi đè các phương thức khácKhi bạn cần ghi đè các phương thức khác, nó không khác lắm so với việc ghi đè student = Student("David", 20020)39. Nếu bạn cần ghi đè hoàn toàn một phương thức, bạn chỉ cần viết phần thân của phương thức mà không cần gọi phương thức của siêu lớp bằng cách sử dụng student = Student("David", 20020)21. Bạn có thể định nghĩa phương thức như thể không có triển khai nào cho cùng một phương thức trong lớp cha, do thứ tự phân giải phương thức (MRO), như được thảo luận tiếp theo Nếu bạn ghi đè một phần phương thức, bạn có thể sử dụng student = Student("David", 20020)21 để sử dụng lại cách triển khai tương tự như siêu lớp, như minh họa bên dướiCập nhật lớp sinh viên Trong lớp student = Student("David", 20020)8 được cập nhật, chúng tôi hiện triển khai phương thức student = Student("David", 20020)2. Đáng chú ý, chúng tôi sử dụng student = Student("David", 20020)21 để tạo đối tượng proxy là đối tượng thể hiện của lớp cha, sao cho chúng tôi có thể gọi phương thức thể hiện của lớp cha trên đối tượng thể hiện proxy này. Do đó, student = Student("David", 20020)21 là duy nhất theo nghĩa nó không chỉ có thể tạo đối tượng proxy cho siêu lớp mà còn có thể là đối tượng proxy cho thể hiện của siêu lớp, cho phép bạn truy cập vào các phương thức thể hiện 5. Hiểu về MRO Khi bạn có một hệ thống phân cấp lớp (lớp cha-lớp con), khi bạn gọi một phương thức trên một thể hiện của lớp con, bạn có thể muốn biết phương thức đó được gọi như thế nào. Ví dụ: lớp con của bạn có thể triển khai các phương thức mà lớp cha không có hoặc triển khai các phương thức mà lớp cha cũng thực hiện Làm thế nào chúng ta có thể biết triển khai nào được sử dụng? . Hình dưới đây cho thấy MRO hoạt động như thế nào Như bạn có thể thấy, khi bạn gọi một phương thức, chẳng hạn như student = Student("David", 20020)83, trước tiên Python sẽ cố gắng giải quyết nó bằng cách định vị nó trong lớp student = Student("David", 20020)8. Nếu được triển khai, việc triển khai này được sử dụng. Nếu không, nó sẽ cố gắng chuyển đến lớp cha của student = Student("David", 20020)8 là student = Student("David", 20020)9, nếu được triển khai, nó sẽ được giải quyết. Nếu không, nó sẽ chuyển đến lớp đối tượng, nơi mà tất cả các lớp tùy chỉnh được kế thừa theo mặc định. Nếu vẫn không giải quyết được, hãy tăng student = Student("David", 20020)87 Bạn thực sự có thể kiểm tra MRO của một lớp bằng cách gọi phương thức student = Student("David", 20020)88 trên lớp, phương thức này cung cấp cho bạn danh sách các lớp theo thứ tự cách giải quyết một phương thức student = Student("David", 20020)4
Khi bạn có nhiều kế thừa, bạn cũng có thể tìm ra MRO bằng cách gọi phương thức student = Student("David", 20020)88. Xin lưu ý rằng nói chung không nên có nhiều kế thừa, điều này có thể làm phức tạp cơ sở mã của bạn. Nói cách khác, nên sử dụng một kế thừa duy nhất 6. Sử dụng các phương pháp được bảo vệ và riêng tư Một cách để đóng gói dữ liệu trong OOP là tạo các phương thức được bảo vệ và riêng tư. Mặc dù Python không thực sự sử dụng khái niệm/từ khóa công khai so với. các phương thức không công khai, chúng ta có thể tạo các phương thức được bảo vệ và riêng tư bằng cách thêm một hoặc hai dấu gạch dưới vào trước tên phương thức, như minh họa bên dưới student = Student("David", 20020)3 Trong đoạn mã trên, student = Student("David", 20020)94 là một phương thức được bảo vệ trong khi student = Student("David", 20020)95 là một phương thức riêng tư. Cả hai phương thức đều không công khai, nghĩa là người dùng bên ngoài lớp không có ý định gọi chúng và bạn có thể lưu ý điều này khi sử dụng IDE (hình sử dụng PyCharm) nơi các phương thức khả dụng được nhắc thông qua gợi ý tự động hoàn thành Sự khác biệt giữa các phương thức được bảo vệ và riêng tư không chỉ là việc sử dụng một hoặc hai dấu gạch dưới và sự khác biệt quan trọng khác là khả năng truy cập của chúng trong các lớp con của lớp. Bạn có thể gọi các phương thức được bảo vệ của lớp cha, nhưng không thể gọi các phương thức riêng tư. Bạn có thể quan sát hiệu ứng này bên dưới student = Student("David", 20020)2 Từ bản in, chúng ta có thể thấy rằng student = Student("David", 20020)94 được gọi mà không gặp bất kỳ sự cố nào. Tuy nhiên, không thể gọi student = Student("David", 20020)95, nâng cao student = Student("David", 20020)87. Nếu chúng tôi xem xét kỹ hơn, chúng tôi lưu ý rằng nó không cố gắng gọi student = Student("David", 20020)95 mà thay vào đó là cố gắng gọi student = Student("David", 20020)00. Điều này có vẻ lạ, nhưng nó được gọi là tính năng mangling. Nghĩa là, khi bạn định nghĩa một phương thức riêng tư, giả sử nó có tên là student = Student("David", 20020)01 trong một lớp có tên là student = Student("David", 20020)02, thay vào đó, phương thức này được đặt tên là student = Student("David", 20020)03
kết luận Trong bài viết này, chúng tôi đã xem xét các điểm chính về việc xác định các lớp con trong Python. Về bản chất, trong hệ thống phân cấp lớp, bạn có một lớp cha, trong đó bạn xác định các thuộc tính và phương thức được chia sẻ Bạn nên có nhiều lớp con kế thừa từ lớp cha này — nếu bạn nhận thấy rằng bạn chỉ đang sử dụng một lớp con duy nhất, điều đó không thể đúng — không cần phải tạo một lớp cha để bắt đầu Lớp con có phải là một thể hiện của lớp cha Python không?Lớp mà một lớp kế thừa từ đó được gọi là lớp cha hoặc lớp cha. Lớp kế thừa từ lớp cha được gọi là lớp con , còn được gọi là lớp kế thừa hoặc lớp con.
Một siêu lớp có thể là một thể hiện của một lớp con không?Có thể tham chiếu một lớp con như một thể hiện của một trong các lớp cha của nó . Chẳng hạn, sử dụng các định nghĩa lớp từ ví dụ trong phần trước, có thể tham chiếu một thể hiện của lớp Car như một thể hiện của lớp Xe.
Lớp con kế thừa gì từ lớp cha Python?Một lớp con kế thừa mọi thứ từ lớp cha của nó , được gọi là kế thừa trong phương pháp hướng đối tượng và lập trình hướng đối tượng. Bằng sự kế thừa, các thuộc tính của lớp cha sẽ không lặp lại trong bất kỳ lớp con nào của nó.
Cách chính xác để tạo một thể hiện của lớp python là gì?Để tạo các thể hiện của một lớp, bạn gọi lớp đó bằng tên lớp và truyền vào bất kỳ đối số nào mà phương thức __init__ của nó chấp nhận . |