2010-04-02 11 views
10

Tôi biết rằng các biến cá nhân riêng tư được truy cập thông qua phương thức thanh toán và phương thức thanh toán công khai của họ.Java - Các biến cá thể riêng có nên được truy cập trong các hàm tạo thông qua phương thức getters và setters không?

Nhưng khi tôi tạo các hàm tạo với sự trợ giúp của IDE, nó khởi tạo trực tiếp các biến mẫu thay vì khởi tạo chúng thông qua các phương thức setter của chúng.

Q1. Vì vậy, tôi nên thay đổi mã IDE được tạo ra cho các nhà xây dựng để khởi tạo các biến mẫu đó thông qua các phương thức setter của chúng.

Q2. Nếu có, thì tại sao IDE không tạo ra các hàm xây dựng theo cách đó?

============================= EDITED ================ =======================

  • tôi sử dụng Eclipse và Netbeans IDE

  • Đó là một câu hỏi chung. Nhưng theo yêu cầu của @Lords thì câu trả lời có phụ thuộc vào việc nhà xây dựng của chúng tôi là công cộng hay được bảo vệ hay gói riêng tư hay riêng tư?

+0

Nhà thầu của bạn có công khai, riêng tư hay cái gì khác không? – Pops

+0

@Lord Tôi đã chỉnh sửa câu hỏi của mình –

+0

Và tôi đã chỉnh sửa câu trả lời của mình. (Trên thực tế hai chỉnh sửa trong kế nhanh chóng.) – Pops

Trả lời

12

Bạn nên không bao giờ gọi phương thức không phải cuối cùng từ một hàm tạo.Một hàm tạo lớp được sử dụng để khởi tạo một đối tượng và đối tượng không ở trạng thái nhất quán cho đến khi hàm tạo trả về. Nếu hàm tạo của bạn gọi một phương thức không phải cuối cùng mà sau đó được ghi đè bởi một lớp con, bạn có thể nhận được kết quả lạ, bất ngờ vì đối tượng không được khởi tạo đầy đủ khi phương thức ghi đè được gọi.

Hãy xem xét ví dụ contrived này:

class A { 
    private int x; 

    public A() { 
     setX(2); 
    } 

    public void setX(int x) { 
     this.x = x; 
    } 

    public int getX() { 
     return x; 
    } 
} 

class B extends A { 
    private int number = 10; 

    @Override   
    public void setX(int x) { 
     // set x to the value of number: 10 
     super.setX(number); 
    } 
} 

public class Test { 
    public static void main(String[] args) { 
     B b = new B(); 
     // b.getX() should be 10, right? 
     System.out.println("B.getX() = " + b.getX()); 
    } 
} 

Kết quả của chương trình này là:

B.getX() = 0 

Lý do là number viên B 's không được khởi tạo lúc setX được gọi, vì vậy giá trị mặc định của nó là 0 được sử dụng.

This article có giải thích kỹ lưỡng hơn, cũng như Hiệu quả Java.

1

Điều đó tùy thuộc. Nếu người định cư của bạn/getters chỉ đơn giản là truy cập vào các thành viên, bạn nên truy cập chúng trực tiếp. Nếu bạn cũng có một số mã cùng với nó, sử dụng setters.

+0

ok nhưng sẽ không tốt hơn khi sử dụng các bộ định cư ngay cả khi người định cư chỉ cài đặt chúng trực tiếp để theo dõi Đóng gói và làm cho nó dễ dàng thêm một số mã trong bộ định cư trong tương lai (nếu cần)? –

+0

Vâng, sau đó nó sẽ không phải là một setter nữa. Bạn cũng nên xem xét, rằng từ một định hướng đối tượng định hướng xem setters không hướng đối tượng (mà đối tượng trong tự nhiên có một "setter"?) – Searles

0

Bạn nên quyết định những trường nào bạn sẽ khởi tạo với hàm tạo và cái nào để initalise với setter. (cả hai đều có thể) Tôi chỉ muốn sử dụng hàm tạo càng nhiều càng tốt và thường không có người định cư.

Điều này có thể được định cấu hình/có thể chọn trong IDE. Nếu không biết IDE của bạn thì không có cách nào để biết tại sao nó hoạt động theo cách của nó.

2

Các nhà xây dựng là để khởi tạo. Khởi tạo các biến cá thể riêng trực tiếp trong hàm tạo. Phương thức xác định hành vi của đối tượng. Hành vi xảy ra sau khi khởi tạo/khởi tạo. Thao tác trạng thái của các biến cá thể của bạn với các phương thức setter của bạn. Đó là suy nghĩ OOP cổ điển và có lẽ lý do tại sao IDE của bạn đang tạo ra mã nó.

0

Câu trả lời hay. Chỉ muốn thêm Eclipse (cái tôi thường sử dụng) có các khuôn mẫu, mà bạn có thể sửa đổi để tạo mã theo cách bạn muốn. Nó có thể giúp điều chỉnh mã theo nhu cầu của bạn.

PS. Tôi thay vì sử dụng setters và getters. Cũng giống như một thói quen, giữ mã chặt chẽ, tôi cảm thấy như nó sẽ dễ dàng hơn để đọc cho người khác nếu tôi giữ thói quen trên tất cả các mã.

0

Trước hết initialization != setters (ít nhất là không phải luôn luôn)

Nhưng IDE chỉ là chơi đẹp với từng tôn kính JavaBean thiết kế mẫu Giả sử thay đổi sở hữu nên xảy ra qua setters.

Vì vậy, đó là vấn đề về thiết kế. Nếu các lớp của bạn đại diện cho các đối tượng có giá trị thuần túy, không có hại gì khi khởi tạo qua = Nhưng nếu các lớp của bạn có khả năng trở thành JavaBean có thay đổi về tài sản không chỉ là init hoặc gán, hãy thực hiện các cuộc gọi set*.

0

Biến cá thể riêng của một lớp phải là (tôi tin là cần) được khai báo bên ngoài bất kỳ hàm tạo nào của lớp. Nếu tôi có thể chia một phần câu hỏi của bạn thành hai phần:

Q1) Nếu các biến mẫu được khởi tạo khi lớp được khởi tạo, không giống như biến cục bộ, tại sao phải làm thêm công việc trong một hàm tạo lớp nhất định (?). Mặc dù bạn không cần phải khởi tạo các biến mẫu (chuỗi private someString; mặc định là null và là hợp pháp), một lý do để làm như vậy là mặc định được trình biên dịch gán có thể không phải là giá trị bạn muốn, hoặc tồi tệ hơn, không chính xác (trình biên dịch nên bắt).

Q2) Giả sử phần trên, ý nghĩa của việc nhận được là gì; bộ; tính chất? Ngoài việc thực tế chúng dễ dàng và thanh lịch hơn, một thuộc tính tương đương, các thuộc tính có thể được sử dụng bất cứ lúc nào trong lớp của bạn (rõ ràng), chúng có thể được sử dụng như các bài tập đơn giản hoặc chứa mã bổ sung (ai đó đã nói điều này để xác thực thông tin) và cuối cùng là dữ liệu nằm trong lớp và do đó dễ dàng gỡ lỗi hơn.

Tất cả điều này đang được nói, bạn có thể có lý do hợp lý hoàn toàn để làm những việc khác với những gì một cuốn sách hoặc người khác nói. Luôn có những nhận thức đối với "quy tắc" và bạn nên viết mã cho phù hợp.