2013-04-19 30 views

Trả lời

17

Hành vi phổ biến nhất là gọi inherited. Vì vậy, nếu tôi rõ ràng không muốn hành vi kế thừa, tôi không gọi inherited. Nếu không, tôi làm. Nếu hành vi kế thừa là một số không có dạng như TObject.Create/Destroy, tôi vẫn gọi inherited.

Cũng lưu ý rằng các situtation cho các nhà xây dựng và destructors có lẽ là một chút khác nhau so với các phương pháp khác. Nó đặc biệt hiếm hoi mà bạn sẽ cần phải bỏ qua một cuộc gọi đến phương pháp kế thừa. Tôi không thể nghĩ ra một ví dụ. Các nhà xây dựng luôn tạo ra và phá hủy các đối tượng khác, vậy làm thế nào bạn có thể suy ngẫm về điều đó?

Tôi biết rằng một số tác giả viết mã bỏ qua inherited khi truy xuất trực tiếp từ TObject, bởi vì họ biết rằng việc triển khai trong TObject không làm gì cả. Tôi không thích điều đó và với tôi đó là một sai lầm để làm điều đó. Các chi tiết thực hiện của TObject không nên bị rò rỉ vào các lớp dẫn xuất.

Tôi chắc chắn rằng TObject.Create/Destroy sẽ luôn là không có hoạt động. Nếu Embarcadero thay đổi thì nhiều mã sẽ bị phá vỡ. Nhưng những gì về một trong các lớp học của bạn. Giả sử bạn có một lớp bắt nguồn từ TObject. Và sau đó bạn có một lớp học có nguồn gốc từ rằng:

TMyClass1 = class 
    .... 
end; 

TMyClass2 = class(TMyClass) 
    .... 
end; 

Bạn không có constructor cho TMyClass1 và một constructor cho TMyClass2 trông như thế này:

constructor TMyClass2.Create; 
begin 
    // no need to call inherited, it's a no-op 
    FMyObj := TBlahBlah.Create; 
end; 

Rồi một ngày bạn sửa đổi các nhà xây dựng TMyClass1 làm một cái gì đó. Bây giờ TClass2 bị hỏng. Vì vậy, tôi sẽ không bao giờ bỏ qua một cuộc gọi đến inherited vì cuộc gọi đó không làm gì cả.

Tình huống cho các phương pháp thể hiện bình thường hơi khác một chút. Nó là hợp lý hơn mà bạn muốn bỏ qua việc thực hiện lớp cơ sở và cung cấp một triển khai hoàn toàn mới. Nhưng đưa ra quyết định dựa trên những gì lớp dẫn xuất muốn làm thay vì có hay không lớp siêu có triển khai thực hiện trống cho phương thức này.

+0

+1 cho phần 'chi tiết triển khai'. Thật vậy, một số phiên bản tương lai của RTL có thể quyết định thực sự đặt một số mã quan trọng trong các phương thức trống này. –

4

Bạn chỉ cần gọi inherited nếu bạn muốn mã của tổ tiên thực thi. Đôi khi bạn cần mã đó, đôi khi bạn không cần. Bạn cũng có thể sử dụng điều kiện và gọi inherited chỉ khi một số điều kiện được đáp ứng và bạn có thể chọn khi làm điều đó (bắt đầu phương thức, kết thúc phương thức, ...).

Do đó, tất cả phụ thuộc vào tình huống.

Here's ví dụ.

+0

Cá nhân tôi làm điều đó ở cuối, đặc biệt nếu tôi đến từ TThread. –

+5

Bạn làm điều đó ở cuối nếu đó là điều đúng để làm, ví dụ như trong một destructor. Và ngay từ đầu nếu đó là điều đúng để làm, ví dụ như trong một nhà xây dựng. Và tương tự như vậy, bạn có thể làm điều đó ở giữa phương thức cho các phương thức ví dụ nhất định. Nếu bạn xuống từ 'TThread', không cần phải gọi hàm tạo kế thừa là điều cuối cùng mà bạn thực hiện trong hàm tạo của mình. Tôi nghĩ rằng bạn đang nhầm lẫn nghĩ rằng các nhà xây dựng kế thừa bắt đầu thực hiện các chủ đề. Nó không. Điều đó xảy ra trong 'AfterConstruction'. –

0

Mặc dù phương thức Tạo/Hủy của TObject không làm bất cứ điều gì trong phiên bản hiện tại, chúng có thể ở một số phiên bản tương lai (có thể, nhưng vẫn có thể). Vì vậy, nó là một PHẢI cho bạn ngay bây giờ?Không, bởi vì nó sẽ không thực hiện bất cứ điều gì, nhưng chỉ vì cha mẹ hiện tại không thêm bất kỳ chức năng nào.

Nếu bạn muốn các đối tượng hậu duệ của bạn luôn thêm chức năng cho cha mẹ, có thể là một ý tưởng hay để liên tục gọi inherited.

Các vấn đề liên quan