Java và C ++ yêu cầu một hàm tạo của lớp cơ sở được gọi vì bố trí bộ nhớ.
Nếu bạn có một lớp BaseClass
với một thành viên field1
và bạn tạo một lớp mới SubClass
có thêm một thành viên field2
, thì một thể hiện SubClass
chứa không gian cho field1
và field2
. Bạn cần một hàm tạo BaseClass
để điền vào field1
, trừ khi bạn yêu cầu tất cả các lớp kế thừa lặp lại BaseClass
khởi tạo trong các hàm tạo của riêng chúng. Và nếu field1
là riêng tư, thì kế thừa các lớp không thể khởi tạo field1
.
Python không phải là Java hay C ++. Tất cả các phiên bản của tất cả các lớp do người dùng định nghĩa có cùng "hình dạng". Về cơ bản chúng chỉ là từ điển trong đó các thuộc tính có thể được chèn vào. Trước khi bất kỳ khởi tạo nào được thực hiện, tất cả các phiên bản của tất cả các lớp do người dùng định nghĩa gần như giống hệt nhau ; chúng chỉ là nơi lưu trữ các thuộc tính chưa lưu trữ.
Vì vậy, nó có ý nghĩa hoàn hảo cho một lớp con Python không gọi hàm tạo của lớp cơ sở của nó. Nó chỉ có thể thêm các thuộc tính chính nó nếu nó muốn. Không có không gian dành riêng cho một số trường nhất định cho mỗi lớp trong cấu trúc phân cấp và không có sự khác biệt giữa một thuộc tính được thêm bởi mã từ một BaseClass
phương thức và một thuộc tính được thêm bởi mã từ một SubClass
phương thức.
Nếu, như thông thường, SubClass
thực sự muốn có tất cả các BaseClass
bất biến được thiết lập trước khi nó tiếp tục thực hiện tùy chỉnh riêng của mình, thì có, bạn chỉ có thể gọi BaseClass.__init__()
(hoặc sử dụng super
, nhưng đôi khi nó phức tạp và có vấn đề riêng). Nhưng bạn không cần phải làm vậy. Và bạn có thể làm điều đó trước, hoặc sau, hoặc với các đối số khác nhau. Chết tiệt, nếu bạn muốn bạn có thể gọi BaseClass.__init__
từ phương thức khác hoàn toàn hơn __init__
; có thể bạn có một số điều khởi tạo lười biếng kỳ lạ đi.
Python đạt được sự linh hoạt này bằng cách giữ cho mọi thứ đơn giản. Bạn khởi tạo các đối tượng bằng cách viết một __init__
phương thức đặt thuộc tính self
. Đó là nó. Nó hành xử chính xác như một phương thức, bởi vì nó chính xác là một phương thức. Không có quy tắc kỳ lạ và không trực quan nào khác về những việc phải được thực hiện trước, hoặc những điều sẽ tự động xảy ra nếu bạn không làm những việc khác. Mục đích duy nhất mà nó cần phục vụ là trở thành một cái móc để thực thi trong quá trình khởi tạo đối tượng để đặt các giá trị thuộc tính ban đầu và nó thực hiện điều đó. Nếu bạn muốn nó làm một cái gì đó khác, bạn viết rõ ràng nó trong mã của bạn.
__init__
phương thức và thậm chí có thể tự động tìm kiếm các lớp con và trang trí chúng.