2016-01-22 18 views
6

Có điều gì đó mơ hồ về ý tưởng này và tôi cần một số giải thích rõ ràng.Ghi đè phương thức "riêng tư" trong java

Vấn đề của tôi là khi sử dụng mã này:

public class B { 

    private void don() { 
     System.out.println("hoho private"); 
    } 
    public static void main(String[] args) { 
     B t = new A(); 
     t.don(); 
    } 
} 

class A extends B { 
    public void don() { 
     System.out.println("hoho public"); 
    } 
} 

Đầu ra là hoho private.

Đây có phải là do hàm chính nằm trong cùng một lớp với phương thức don hoặc do ghi đè?

Tôi đã đọc ý tưởng này trong một cuốn sách và khi tôi đặt hàm main trong một lớp khác, tôi nhận được lỗi trình biên dịch.

+1

Một số đọc tốt: http://stackoverflow.com/questions/2000137/overriding-private- phương pháp-trong-java – CollinD

+1

bạn đang ẩn và không ghi đè. – Rahul

+1

Ngoài việc không hiển thị bên ngoài loại (và có lẽ có liên quan hơn đến câu hỏi ở đây), các phương thức riêng tư * không đa hình * - chỉ có phương thức được định nghĩa trên loại biểu thức sẽ được gọi ra; không có công văn động nào xảy ra. Trong ví dụ được hiển thị, * biểu thức 't' là kiểu' B' * và do đó 't.don()' sẽ * luôn luôn * được gọi là 'don' của B. * Loại thời gian chạy 'A' không liên quan * và không cho phép 'ghi đè' phương thức riêng tư như vậy. – user2864740

Trả lời

6

Bạn không thể ghi đè phương thức private. Không hiển thị nếu bạn truyền A đến B. Bạn có thể ghi đè phương thức protected, nhưng đó không phải là những gì bạn đang làm ở đây (và có, tại đây nếu bạn di chuyển main đến A thì bạn sẽ nhận được phương pháp khác. ghi đè,

class A extends B { 
    @Override 
    public void don() { // <-- will not compile if don is private in B. 
     System.out.println("hoho public"); 
    } 
} 

trong trường hợp này tại sao không trình biên dịch cung cấp một lỗi cho việc sử dụng t.don() đó là private?

The Java Tutorials: Predefined Annotation Types nói (trong mệnh t)

Mặc dù không bắt buộc phải sử dụng chú thích này khi ghi đè phương thức, nó giúp ngăn ngừa lỗi. Nếu phương thức được đánh dấu bằng @Override không ghi đè chính xác phương thức trong một trong các lớp bậc trên của nó, trình biên dịch sẽ tạo ra lỗi.

+0

Cảm ơn bạn Elliott, nhưng làm thế nào chức năng chính có thể sử dụng t.don() trong khi nó là một phương pháp riêng bên trong lớp B –

+1

@ basel Bởi vì nó là ** trong ** lớp 'B'. Mỗi hàm ** trong lớp ** 'B' có thể truy cập các phương thức riêng trong lớp' B'. –

+0

ok cảm ơn bạn rất nhiều –

4

Bạn có thể không override một phương pháp riêng, nhưng bạn có thể giới thiệu một trong một lớp học có nguồn gốc mà không có một vấn đề. Lớp dẫn xuất không thể truy cập phương thức riêng trên tổ tiên.

Kể từ t là về đối tượng của loại B, gọi phương thức don() sẽ invoque phương pháp quy định tại B. Nó thậm chí không biết rằng có một phương thức có tên cũng don() ở lớp A

3

Không, không thể ghi đè phương thức riêng tư vì không thể nhìn thấy phương thức này từ bất kỳ lớp nào khác. Bạn đã khai báo một phương thức mới cho lớp con của bạn mà không có liên quan đến phương thức siêu lớp. Một cách để xem xét nó là tự hỏi xem liệu sẽ là hợp pháp khi viết super.func() trong lớp Derived.

4

là điều này bởi vì chức năng chính là trong lớp giống như phương pháp "don"

Không, đó là vì A 's don() không liên quan đến B' s don() phương pháp, mặc dù có cùng tên và danh sách đối số. private phương thức được ẩn bên trong lớp học của họ. Họ không thể được gọi trực tiếp bởi người gọi bên ngoài, chẳng hạn như main phương pháp trong trường hợp của bạn, bởi vì chúng được đóng gói bên trong lớp.Họ không tham gia ghi đè phương pháp.

+0

trong trường hợp này thì tại sao trình biên dịch không cung cấp lỗi biên dịch cho việc sử dụng t.don() là riêng tư? –

2

thành viên private là không hiển thị cho bất kỳ lớp học khác, ngay cả trẻ em

Bạn không có thể ghi đè một phương pháp riêng, nhưng sau đó một lần nữa, bạn không thể gọi nó là một trong hai. Tuy nhiên, bạn có thể tạo một phương thức giống hệt với cùng tên trong con.

public class A 
{ 
    private int calculate() {return 1;} 
    public void visibleMethod() 
    { 
     System.out.println(calculate()); 
    }; 
} 

public class B extends A 
{ 
    private int calculate() {return 2;} 
    public void visibleMethod() 
    { 
     System.out.println(calculate()); 
    }; 
} 

Nếu bạn gọi A.visibleMethod() nó in ra 1.

Nếu bạn gọi B.visibleMethod() nó in 2.

Nếu bạn không thực hiện các tính toán cá nhân () trong phương thức B, nó sẽ không biên dịch vì phương thức công khai gọi là không thể xem phương thức riêng trong A.

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