2008-12-04 32 views
8

Công trình này:Làm cách nào tôi có thể gọi phương thức tổ tiên `Kế thừa` trong các hàm ảo bị ghi đè?

constructor TMyObj.Create; 
begin 
inherited; 
end; 

Tại sao điều này không hoạt động?

function TMyObjEx.Import(CONST FileName: string; CONST x, y, z: Integer): string; 
begin 
result:= inherited; // Import(FileName, x, y, z); <--- Compiler says: "incompatible types" 
//do other stuff here 
end; 

Tuyên bố của TMyObjEx là như thế này:

TYPE 

TMyObj = class(TChObj) 
     private 
     protected 
     public 
     function Import (CONST FileName: string; CONST x, y, z: Integer): string; virtual;  
    end; 

TMyObjEx= class(TMyObj) 
      private 
      protected 
      public 
      function Import(CONST FileName: string; CONST x, y, z: Integer): string; override; 
     end; 
+0

Stackoverflow phải có một danh mục khác "phê bình không có cấu trúc" nơi người hỏi chỉ trích ngôn ngữ, thư viện hoặc công cụ cải trang thành câu hỏi. – nurettin

Trả lời

1

Lúc đầu, tôi nghĩ rằng bạn chỉ có thể sử dụng inherited nếu bạn đã không quan tâm đến kết quả của chức năng, rằng dường như không phải là trường hợp. Việc gọi các phương thức hàm được thừa kế yêu cầu tên và tham số của phương thức. Nó là như vậy. Bạn cũng cần phải đề cập đến tên phương thức nếu bạn đang truyền các tham số khác nhau từ các phương thức mà phương thức hiện tại nhận được, hoặc nếu bạn đang gọi một phương thức hoàn toàn khác.

8

Các tham số tự động chuyển qua không hoạt động khi bạn cần kết quả của phương thức. Bạn cần điền tên của phương thức và tham số, xin lỗi.

+0

Câu trả lời của bạn là hữu ích, tại sao xin lỗi;) –

-1

Có vẻ các tài liệu Delphi có một lỗ đen ... (Oooooh, những tin tức tuyệt vời về nó là gì?)

xét nghiệm của tôi cho thấy rằng việc sử dụng thừa hưởng từ khóa mà không cần bất cứ điều gì sau khi nó chỉ hoạt động trên constructor, phương pháp hủy và thủ tục. Trên Chức năng các phương thức không hoạt động AT ALL.

Tuy nhiên, tôi chưa bao giờ phát hiện ra vì tôi có thói quen gọi phương thức được kế thừa đầy đủ, ngay cả khi tôi không cần nó (động lực: để có thể sử dụng Ctrl + Nhấp chuột trái trên đó và làm theo dòng mã dễ dàng hơn mà không cần gỡ lỗi).

+0

Nó cũng là một kiểm tra an toàn hữu ích + cân bằng trong sự hiện diện của ghi đè quá tải, để đảm bảo bạn thực sự đang gọi quá tải thừa bạn thực sự có ý nghĩa. 9/10 nó là phương pháp kế thừa trực tiếp, nhưng sau đó có 1 trong 10 mà bắt bạn ra .... :) – Deltics

+0

@ Deltics, đồng ý. Nó luôn luôn là 10% cuối cùng mà mất 90% thời gian ;-) –

10

Đây là câu trả lời đúng.

Cách thích hợp để làm điều này là như bạn đã nói ở trên:

function TMyObjEx.Import(CONST FileName: string; CONST x, y, z: Integer): string; 
begin 
result:= inherited Import(FileName, x, y, z); 
//do other stuff here 
end; 

Cách bạn đang muốn làm điều đó không được hỗ trợ bởi ngôn ngữ.

Vì vậy, cuối cùng câu trả lời cho câu hỏi của bạn về "Tại sao điều này cũng không hoạt động?" là vì đó không phải là cách ngôn ngữ được thiết kế.

+1

Vâng OK, tôi biết điều đó, nhưng tại sao? ;) (nghiêm túc, tôi muốn quan tâm đến lý do kỹ thuật cấp thấp vì sao nó làm việc cho các thủ tục chứ không phải cho các chức năng) –

+0

Để làm điều đó theo cách bạn đang thử đòi hỏi mức độ giả định cao hơn nhiều. –

+3

Nhưng đây là một giả định tự nhiên. Nó hoạt động cho mọi thứ, ngoại trừ chức năng - và khi bạn nhìn vào tài liệu, nó đề cập đến 'phương pháp', mà đối với tôi có nghĩa là hàm, thủ tục, hàm tạo và hàm hủy. –

6

Là tại sao nó không được hỗ trợ, Hallvard đã viết một plausible explanation vài năm trước đây trên blog của mình:

Một caveat với "thừa hưởng"; cú pháp là nó không được hỗ trợ cho các chức năng. Đối với các hàm , bạn phải sử dụng cú pháp rõ ràng bao gồm tên phương thức và bất kỳ đối số nào. Ví dụ:

[một số mã]

này có thể trông giống như một giám sát trong việc thiết kế ngôn ngữ Delphi, nhưng tôi nghĩ rằng đó là có chủ ý. Lý do đằng sau nó có lẽ là nếu TMyClass.MethodC là trừu tượng (hoặc được tạo trừu tượng trong tương lai), việc gán kết quả trong lớp con cháu sẽ bị xóa và do đó kết quả có giá trị đột nhiên không xác định. Điều này chắc chắn sẽ gây ra các lỗi tinh tế.

+0

Giải thích "hợp lý" như thế nào? Cho dù bạn gọi một hàm trừu tượng được thừa hưởng, hoặc ngầm định, hàm trừu tượng kế thừa không trả về (không có gì để gọi, không có gì để trả về) do đó kết quả vẫn chưa thực sự được gán ngay cả khi nó có thể xuất hiện * để được khởi tạo trong chức năng ghi đè. – Deltics

+3

vì bạn có thể gọi được kế thừa; và nếu không có hàm phù hợp trong tổ tiên thì câu lệnh đơn giản bị bỏ qua. Nhưng nếu bạn sử dụng phương thức kế thừa(); và không có phương thức phù hợp trong lớp tổ tiên nó gây ra lỗi thời gian biên dịch. Dựa trên đó người ta sẽ mong đợi rằng kết quả: = kế thừa; bị bỏ qua nếu không có phương thức được kế thừa để gọi. Nhưng điều này sau đó lá kết quả chưa được giao. Không gọi một thủ tục không có tác dụng phụ, không gọi một hàm cũng loại bỏ nhiệm vụ. –

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