Getters và setters hoạt động như thế nào?


107

Tôi đến từ thế giới php. Bạn có thể giải thích getters và setters là gì và có thể cho bạn một số ví dụ không?


@ yegor256 Tôi hiểu sự tương tự dog & ball của bạn và tôi thậm chí ủng hộ nó, nhưng còn khi một đối tượng "sinh vật sống" lưu trữ giá trị nguyên thủy không thường xuyên, ví dụ như ID thì sao? Điều gì sẽ xảy ra nếu bạn muốn vượt xa phép gán đơn giản nhưng không muốn viết một lớp mới chỉ để xử lý các giá trị nguyên thủy?
Jacksonkr

Câu trả lời:


127

Hướng dẫn không thực sự cần thiết cho việc này. Đọc về cách đóng gói

private String myField; //"private" means access to this is restricted

public String getMyField()
{
     //include validation, logic, logging or whatever you like here
    return this.myField;
}
public void setMyField(String value)
{
     //include more logic
     this.myField = value;
}

11
vì vậy getter chỉ là một phương thức nhận một trường riêng tư và setter đang thiết lập một trường mới. cảm ơn cho lời giải thích tuyệt vời bởi mã
ajsie

1
bạn có thể chuyển một tham số cho một getter không?
ajsie

2
noname: Không và không. Getter là cách để nhận một giá trị nhưng KHÔNG để lộ giá trị có trong một trường, nghĩa là nếu bạn gọi someObj.getTime().setHour(5)nó sẽ không ảnh hưởng đến someObjtrạng thái bên trong của trường. Ngoài ra, setters và getters (trình truy cập và trình đột biến theo tên lạ của chúng) có một chữ ký phương thức rất nghiêm ngặt có nghĩa là getter không có bất kỳ tham số nào. Các phương pháp nói chung dù sao cũng chỉ nên làm một việc.
Esko

4
@noname: Khi những thứ đơn giản được đặt tên phức tạp / lớn / trừu tượng, bạn có cái được gọi là "mẫu thiết kế" .... Và đây là một ví dụ về Mẫu giải thích khái niệm đệ quy mà tôi vừa phát minh ;-)
namespaceform

3
@qed: thisTừ khóa là tùy chọn trừ khi có xung đột với thứ có phạm vi cụ thể hơn. Trong ví dụ bạn đã đưa ra, bộ thiết lập được tạo sẽ có một tham số duy nhất có tên trùng với tên trường, do đó this.fieldName = fieldName, được sử dụng để phân biệt rằng trường đang được gán cho chứ không phải tham số được gán cho chính nó như fieldName = fieldnamesẽ đạt được. Không có xung đột như vậy tồn tại trong getter.
Paul Creasey

39

Trong Java getters và setters là những hàm hoàn toàn bình thường. Điều duy nhất làm cho họ trở thành người lập công hoặc người định cư là quy ước. Một getter cho foo được gọi là getFoo và setter được gọi là setFoo. Trong trường hợp boolean, getter được gọi là isFoo. Họ cũng phải có một khai báo cụ thể như trong ví dụ này về getter và setter cho 'name':

class Dummy
{
    private String name;

    public Dummy() {}

    public Dummy(String name) {
        this.name = name;
    }

    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

Lý do sử dụng getters và setters thay vì công khai các thành viên của bạn là nó giúp bạn có thể thay đổi việc triển khai mà không cần thay đổi giao diện. Ngoài ra, nhiều công cụ và bộ công cụ sử dụng sự phản chiếu để kiểm tra các đối tượng chỉ chấp nhận các đối tượng có getters và setters. Ví dụ, JavaBeans phải có getters và setters cũng như một số yêu cầu khác.


9
Không phải các hàm tạo đó không có 'void'?
Jason Hartley

Void thực sự cần thiết ở đây. Nếu bạn không có nó, bạn nhận được:error: invalid method declaration; return type required
Dan

3
Void không bắt buộc ở đây
Shashi Kiran

2
@JasonHartley: Một hàm tạo không có kiểu trả về.
wassimans

@Mark Byers Vì vậy, phương thức khởi tạo được sử dụng để khởi tạo thể hiện và trình thiết lập được sử dụng để thay đổi bất kỳ thuộc tính nhất định nào. Điều này có chính xác?
carloswm85

12
class Clock {  
        String time;  

        void setTime (String t) {  
           time = t;  
        }  

        String getTime() {  
           return time;  
        }  
}  


class ClockTestDrive {  
   public static void main (String [] args) {  
   Clock c = new Clock;  

   c.setTime("12345")  
   String tod = c.getTime();  
   System.out.println(time: " + tod);  
 }
}  

Khi bạn chạy chương trình, chương trình bắt đầu bằng nguồn điện,

  1. đối tượng c được tạo ra
  2. hàm setTime()được gọi bởi đối tượng c
  3. biến timeđược đặt thành giá trị được truyền qua
  4. hàm getTime()được gọi bởi đối tượng c
  5. thời gian được trả lại
  6. Nó sẽ đến todtodđược in ra

10

Bạn cũng có thể muốn đọc " Tại sao phương pháp getter và setter là xấu ":

Mặc dù các phương thức getter / setter rất phổ biến trong Java, nhưng chúng không đặc biệt là hướng đối tượng (OO). Trên thực tế, chúng có thể làm hỏng khả năng bảo trì mã của bạn. Hơn nữa, sự hiện diện của nhiều phương thức getter và setter là một dấu hiệu báo trước rằng chương trình không nhất thiết phải được thiết kế tốt từ góc độ OO.

Bài viết này giải thích lý do tại sao bạn không nên sử dụng getters và setter (và khi nào bạn có thể sử dụng chúng) và đề xuất một phương pháp thiết kế sẽ giúp bạn thoát khỏi tâm lý getter / setter.


3

1. Getters / setters tốt nhất là thông minh.

Đây là một ví dụ javascript từ mozilla:

var o = { a:0 } // `o` is now a basic object

Object.defineProperty(o, "b", { 
    get: function () { 
        return this.a + 1; 
    } 
});

console.log(o.b) // Runs the getter, which yields a + 1 (which is 1)

Tôi đã sử dụng RẤT NHIỀU vì chúng rất tuyệt vời . Tôi sẽ sử dụng nó khi yêu thích mã hóa + hoạt ảnh của mình. Ví dụ: tạo một bộ định giá giao dịch với một Numberbộ hiển thị số đó trên trang web của bạn. Khi bộ cài đặt được sử dụng, nó sẽ chuyển số cũ thành số mới bằng cách sử dụng tweener . Nếu số ban đầu là 0 và bạn đặt nó thành 10 thì bạn sẽ thấy các số chuyển nhanh từ 0 đến 10, giả sử là nửa giây. Người dùng yêu thích nội dung này và thật thú vị khi tạo ra.

2. Getters / setters trong php

Ví dụ từ sof

<?php
class MyClass {
  private $firstField;
  private $secondField;

  public function __get($property) {
    if (property_exists($this, $property)) {
      return $this->$property;
    }
  }

  public function __set($property, $value) {
    if (property_exists($this, $property)) {
      $this->$property = $value;
    }

    return $this;
  }
}
?>

trích dẫn:


2

Đây là một ví dụ để giải thích cách đơn giản nhất để sử dụng getter và setter trong java. Người ta có thể làm điều này theo cách đơn giản hơn nhưng getter và setter có một điều đặc biệt đó là khi sử dụng private member của lớp cha trong lớp con trong kế thừa. Bạn có thể thực hiện điều đó bằng cách sử dụng getter và setter.

package stackoverflow;

    public class StackoverFlow 

    {

        private int x;

        public int getX()
        {
            return x;
        }

        public int setX(int x)
        {
          return  this.x = x;
        }
         public void showX()
         {
             System.out.println("value of x  "+x);
         }


        public static void main(String[] args) {

            StackoverFlow sto = new StackoverFlow();
            sto.setX(10);
            sto.getX();
            sto.showX();
        }

    }

Tôi sẽ không phản đối bạn (không đáng để nỗ lực). Xin lưu ý rằng (1) Bạn đã trả lời cho một câu hỏi Java , ngôn ngữ chương trình phải ở đâu trong Java. (2) Nếu bạn muốn đăng, hãy đảm bảo rằng bố cục được thực hiện chính xác. (3) Việc bạn sử dụng tính năng đóng gói (getter (hoặc accessor) và setters (hoặc mutators)) của bạn không chính xác. Vui lòng tra cứu tính đóng gói có nghĩa là gì ... (Kiểm tra câu trả lời được bình chọn)
KarelG

1
@KarelG xin lỗi tôi đã không đọc các thẻ. tôi đã cập nhật nó lên java. cảm ơn vì đã nhận ra tôi.
Bashir ahmad
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.