2009-04-10 51 views
5

Tôi có các lớp sau:Siêu lớp có không gọi phương thức ghi đè không?

class foo { 
    public void a() { 
     print("a"); 
    } 
    public void b() { 
     a(); 
    } 
} 

class bar extends foo { 
    public void a() { 
     print("overwritten a"); 
    } 
} 

Khi tôi bây giờ gọi bar.b() Tôi muốn nó gọi phương thức ghi đè một() trong foo. Nó, tuy nhiên, in "a".

+3

Xin lỗi giáo lý: Nó được gọi là "ghi đè" chứ không phải "ghi đè". – erickson

+0

Mã như bạn đã viết nó sẽ hoạt động như bạn mong đợi - vì nhiều câu trả lời dưới đây gợi ý để có được kết quả bạn đang nhận được, bạn phải làm điều gì đó khác trong mã mà bạn không hiển thị ở đây. – Eborbob

Trả lời

7

Khi tôi chạy như sau:

public class Program { 
    public static void main(String[] args) { 
     bar b = new bar(); 
     b.b(); 
    } 
} 

class foo { 
    public void a() { 
     System.out.printf("a"); 
    } 
    public void b() { 
     a(); 
    } 
} 

class bar extends foo { 
    public void a() { 
     System.out.printf("overwritten a"); 
    } 
} 

tôi nhận được kết quả như sau:

overwritten a 

đó là những gì tôi mong đợi để xem.

+0

Bạn đã đánh bại tôi một phút. Tôi nhận được cùng một đầu ra. – Eddie

+0

Có thể anh ta đánh bạn bằng cách đăng bài, nếu không, tôi tin rằng, chúng tôi đã có cách này đầu ra trước khi câu hỏi này được đăng. –

9

Có thể bạn đang cố gắng sử dụng các phương pháp tĩnh, sẽ không hoạt động vì chúng không bị ghi đè.

Một cách tốt để kiểm tra là để thêm chú thích @ Override để bar.a() và xem nếu trình biên dịch cung cấp cho bạn một lỗi mà một() không thực sự overidding bất cứ điều gì

+2

+1 cho đề xuất @Override – Rob

0

Bạn có thể bị nhầm lẫn nếu bạn đang đến từ C# hoặc một số ngôn ngữ khác, nơi bạn phải khai báo rõ ràng các hàm ảo và/hoặc các hàm ghi đè.

Trong Java, tất cả các hàm mẫu là ảo và có thể bị ghi đè - trừ khi chúng được khai báo là riêng tư và/hoặc cuối cùng.

Không cần chỉ định chú thích @Override mới để làm như vậy, việc thêm chú thích chỉ định rằng ý định của bạn là ghi đè và sẽ gây cảnh báo hoặc lỗi nếu nó không ghi đè. (Nếu bạn vô tình viết sai chính tả tên phương thức).

Ví dụ của Andrew cho biết cách hoạt động của tính năng này.

10

Hai lớp học của bạn có trong các gói khác nhau không? Và các phương thức lớp foo của bạn có được khai báo công khai, được bảo vệ hay riêng tư hay gói cục bộ không? Rõ ràng nếu chúng là riêng tư, điều này sẽ không hoạt động. Có lẽ ít rõ ràng hơn, là nếu chúng là gói địa phương (nghĩa là không có phạm vi công cộng/được bảo vệ/riêng tư) thì bạn chỉ có thể ghi đè chúng nếu bạn ở trong cùng một gói với lớp gốc.

Ví dụ:

 
package original; 
public class Foo { 
    void a() { System.out.println("A"); } 
    public void b() { a(); } 
} 

package another; 
public class Bar extends original.Foo { 
    void a() { System.out.println("Overwritten A"); } 
} 

package another; 
public class Program { 
    public static void main(String[] args) { 
    Bar bar = new Bar(); 
    bar.b(); 
    } 
} 

Trong trường hợp này, bạn vẫn sẽ nhận được 'A'. Nếu bạn khai báo phương thức a() ban đầu trong Foo công khai hoặc được bảo vệ, bạn sẽ nhận được kết quả mong đợi.

+2

Đây là vấn đề của tôi; thay đổi phương thức siêu kiểu để bảo vệ nó. Những gì tôi không nhận được là lý do tại sao thẻ @Override trên phương thức loại phụ không làm cho trình biên dịch cung cấp cho tôi thông báo lỗi nếu nó không hoạt động. – shieldgenerator7

0

Từ miệng của ngựa:

http://download.oracle.com/javase/tutorial/java/IandI/override.html

"Phiên bản của phương pháp ghi đè đó được gọi là một trong subclass Phiên bản của phương pháp ẩn mà được gọi phụ thuộc vào việc nó được gọi. từ lớp cha hoặc lớp con. "

Vì vậy, nếu cả hai đều là phương thức tĩnh và bạn gọi phương thức từ lớp siêu, thì phương thức siêu lớp được gọi, không phải phương thức lớp con. Vì vậy, thực sự, không có sự ghi đè nào đang diễn ra.

-1

Trong khi tôi đang làm việc trên một chương trình Android, tôi đã có cùng một vấn đề trên các lớp Java của tôi. Nó bật ra rằng vấn đề không phải là trong các lớp học nhưng cách khung Android xử lý đầu ra màn hình.

ví dụ nếu đầu ra được lập trình trong phương thức onCreate() trong lớp cha, Android không tìm nạp chính xác đầu ra của các phương thức ghi đè từ lớp con ngoài con đầu tiên. Thành thật mà nói tôi không hiểu toàn bộ lệnh gọi phương thức.

Để giải quyết vấn đề tôi chỉ đơn giản là lập trình đầu ra trong onResume() và bây giờ nó có vẻ hoạt động tốt.

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