2012-02-09 35 views
6

Tôi có thể gọi biến theo 2 cách.Cách thích hợp để nhận biến từ một lớp khác

Một chỉ là để làm điều đó như thế này:

MyClass myClass = new MyClass();  

myLocalVar = myClass.myVarVal; 

Và cách khác là sử dụng một getter như thế này:

myLocalVar = myClass.getMyVarVal(); 

Cả hai cách đều làm việc tốt, nhưng tôi đã tự hỏi những gì sẽ là cách hiệu quả nhất/thích hợp để làm điều này?

Cảm ơn

+3

Rất nhiều tài nguyên [tại đây] (http://stackoverflow.com/q/1568091/387852), [tại đây] (http://stackoverflow.com/q/565095/387852) và [tại đây] (http) : //stackoverflow.com/q/996179/387852) chẳng hạn. –

+0

Nhưng nếu tôi có 50 biến mô tả một đối tượng. Ví dụ, cho phép nói rằng tôi có một đối tượng được gọi là xe hơi, và sau đó tôi có một loạt các biến như carType, carColor, carHP, carMaker, carName, carWheelBase, carMPG, carTransmission, carEngine, vv ... tôi có cần phải thực hiện một getter và setter cho mỗi người? Điều đó có vẻ giống như một TON của mã hóa thêm .... – SkyeBoniwell

+2

IDE hiện đại (như Eclipse) có thể làm điều đó tự động. Nhưng bạn cũng nên tự hỏi mình nếu bạn cần để lộ những biến đó cho thế giới bên ngoài. Bạn có vi phạm các nguyên tắc đóng gói tốt không? –

Trả lời

11

Cả hai kỹ thuật là khủng khiếp, nhưng sử dụng getter là thực tế phổ biến (và an toàn hơn).

Để truy cập thành viên dữ liệu công cộng (trường công khai hoặc thuộc tính công khai) của một lớp, bạn phải biết chi tiết triển khai của lớp (tên thành viên dữ liệu và loại thành viên dữ liệu). Đây là một điều xấu; nó phá vỡ khái niệm OOP "ẩn thông tin" và tăng "khớp nối".

Sử dụng trình khởi động cũng xấu (như trong thực tiễn OOP không tốt) vì các đối tượng không chỉ là trình bao bọc xung quanh dữ liệu; các đối tượng có nghĩa vụ đóng gói chức năng và dữ liệu. "lưu trữ giá trị này ở đây để tôi có thể nhận được sau này" không phải là chức năng; nó là chức năng hoot (như trong một con khỉ trong lồng hooting). Getters là; tuy nhiên, một thực hành được chấp nhận trong java (và các ngôn ngữ OOP-lite khác như C++ và C#).

Vì sợ rằng bạn nghĩ rằng tôi là một số tháp ngà tinh khiết nhất, tất nhiên tôi sử dụng getters; Tôi sử dụng java, vì vậy tôi sử dụng getters.

Getters là tốt cho việc thực hiện công việc (không chơi chữ), chỉ cần không đi bộ xung quanh tin rằng "IR gud OOP Prgmr", bởi vì nếu bạn sử dụng getters bạn không phải là một "lập trình oop tốt", bạn chỉ một lập trình viên đã hoàn thành công việc.

Chỉnh sửa: Có lẽ một cách tốt hơn.

Cách tốt hơn là không sử dụng getters, nhưng thay vào đó thiết kế các lớp học của bạn để chúng lộ ra chức năng không phải dữ liệu. Trong thực tế, có một điểm mà điều này bị phá vỡ; ví dụ, nếu bạn cần hiển thị một địa chỉ trên một trang JSP, bạn đặt một bean trong yêu cầu (hoặc session hoặc blah) với địa chỉ và hiển thị các giá trị bằng cách sử dụng getters. Một cách "tinh khiết hơn" là đặt một bean tiếp xúc với "hiển thị địa chỉ trên một jsp" chức năng.

Chỉnh sửa2: Có lẽ một ví dụ tốt hơn.

Giả sử tôi làm việc cho một công ty điện thoại, ở Hoa Kỳ và tôi có một đối tượng đại diện cho một số điện thoại của khách hàng. Điều này có thể trông giống như sau:

public class CustomerPhoneNumber 
{ 
    private String npa; // numbering plan area (google search nanp for more details) 
    private String nxx; // exchange. 
    private String serviceNumber; 

    public String toString() 
    { 
    return "(" + npa + ") " + nxx + "-" + serviceNumber; 
    } 

    public boolean equals(Object object) 
    { 
    ... standard equals implementation (assume this works) 
    } 
} 

Bây giờ nói tôi nhận được một số điện thoại như một đầu vào từ một trang web dưới dạng String inputPhoneNumber. Với mục đích thảo luận, lớp nhận đầu vào này được gọi là "servlet".

Làm cách nào để trả lời câu hỏi này: "Số điện thoại đầu vào có trong danh sách các đối tượng CustomerPhoneNumber của tôi không?"

Tùy chọn 1 là đặt thành viên npa, nxx và serviceNumber thành công và truy cập chúng. Thật là kinh khủng.

Tùy chọn 2 cung cấp getters cho npa, nxx và số dịch vụ và so sánh chúng với đầu vào. Cũng khủng khiếp, quá nhiều chi tiết nội bộ tiếp xúc.

Tùy chọn 3 cung cấp trình trả về trả về số điện thoại đã định dạng (tôi gọi đây là toString() ở trên). Điều này thông minh hơn nhưng vẫn khủng khiếp vì servlet phải biết định dạng sẽ được getter sử dụng và đảm bảo rằng đầu vào được định dạng theo cùng một cách.

Tùy chọn 4 (Tôi gọi đây là "Chào mừng bạn đến OOP") cung cấp một phương thức nhận một chuỗi và trả về true nếu phù hợp với số dịch vụ khách hàng. Điều này là tốt và có thể trông như thế này (tên là dài, nhưng đủ cho ví dụ này):

public boolean doesPhoneNumberMatchThisInput(final String input) 
{ 
    String formattedInput; 
    String formattedCustomerPhoneNumber = npa + nxx + serviceNumber; 

    formattedInput = ... strip all non-digits from input. 

    return StringUtils.equals(formattedCustomerPhoneNumber, formattedInput); 
} 

Đây là người chiến thắng vì không có chi tiết thi hành được tiếp xúc. Cũng có thể sử dụng toString để xuất số điện thoại trên trang JSP.

ChuỗiUtils là một phần của Apache Commons Lang.

+0

như vậy là có một cách tốt hơn hoặc là getters chỉ là một điều ác cần thiết? – SkyeBoniwell

+0

Có [bài viết xuất sắc tại đây] (http://www.yegor256.com/2014/09/16/getters-and-setters-are-evil.html) dành cho những người tìm kiếm giải thích kỹ lưỡng hơn (xem phần *) Một phần bóng và chó * cho một sự tương tự rất dễ hiểu.) –

8

Vì lợi ích của encapsulation bạn nên luôn luôn đi với phương án thứ hai.

myLocalVar = myClass.getMyVarVal(); 

Hiệu quả khôn ngoan bạn rất có thể sẽ không nhận thấy sự khác biệt.

4

LUÔN LUÔN sử dụng getter và setter để truy cập các thuộc tính của bạn!

Bạn cũng nên xem this.

1

myClass.getMyVarVal() chậm hơn vì đây là cuộc gọi phương thức và vì vậy nó tạo lối vào trên ngăn xếp cho giá trị trả về, v.v. Nhưng thực hành OOP tốt hơn để sử dụng getters.

+2

Ngôn ngữ Java không quy định rằng lời gọi phương thức nên được thực hiện như thế. Trong thực tế, nhiều khả năng phương pháp như vậy sẽ được inlined. – aioobe

1
myLocalVar = myClass.getMyVarVal(); 

nó sẽ được tốt để sử dụng nó nếu bạn đang làm việc với OOP khái niệm

2

Chỉ cần tạo đối tượng và object.variablename; hoặc object.methodName(); có thể được sử dụng để thực hiện tham chiếu không tĩnh ... không yêu cầu sử dụng getter.

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