Helpex - Trao đổi & giúp đỡ Đăng nhập
47

Tôi chỉ đang học lập trình và đã quyết định dùng thử Ruby. Tôi chắc rằng đây là một câu hỏi ngu ngốc, nhưng người hướng dẫn đang nói về phương pháp setter và getter, và tôi bối rối. Đây là ví dụ:

class Human
  def noise=(noise)
    @noise = noise
  end

  def noise
    @noise
  end
end

Từ điều này, lớp được khởi tạo và tôi có thể đưa ra điều này:

man = Human.new
man.noise=("Howdie!")
puts man.noise

Kết quả này trong Howdie!

Bây giờ điều làm tôi bối rối là người hướng dẫn đang nói nếu không có phương thức getter (phương thức thứ 2 trong số hai phương pháp) thì không có cách nào để tương tác với biến cá thể @noise.

Nhưng khi tôi xóa phương thức getter, tôi vẫn có thể truy cập @noise, hãy xem ví dụ:

class Human
  def noise=(noise)
    @noise = noise
  end
end

man = Human.new
puts man.noise=("Howdie!")

Điều này hoạt động giống như khi phương thức getter mà nó sử dụng.

Nên bây giờ tôi đang bối rối. Tại sao cần có getter? Người hướng dẫn có nghĩa là gì khi không thể truy cập biến cá thể mà không có nó? Có khả năng anh ta đang sử dụng phiên bản Ruby cũ hơn không?

Cảm ơn trước sự giúp đỡ của bạn.

47 hữu ích 1 bình luận 47k xem chia sẻ
35

Bạn có thể tương tác với biến phiên bản đó từ các phương thức khác thuộc phiên bản đó, ngay cả khi không có getter:

def noise=(noise)
  @noise = noise
end

def last_noise
  @noise
end

Không cần phải có một getter được xác định có cùng tên với phương thức; cả hai không được liên kết với nhau. Getter là cần thiết để "lấy" giá trị của biến cá thể, nhưng chỉ trong một cú pháp ngắn gọn .

Điều đang xảy ra trong ví dụ của bạn là bạn đang khởi tạo một đối tượng mới ( Human.new), và sau đó sử dụng một phương thức ( noise=, vâng, tên phương thức chứa =ký hiệu) chỉ xảy ra để xác định một biến thể hiện (nghĩa là một biến chỉ cho trường hợp đó), và cuối cùng truy xuất biến cá thể đó bằng một lệnh gọi phương thức khác .

Bạn thực sự có thể sử dụng instance_variable_getđể lấy biến cá thể mà không cần xác định bất kỳ getter nào :

man = Human.new
man.noise = "Howdie"
man.instance_variable_get("@noise")

Điều này sẽ trả về "Howdie", mặc dù không có getter được xác định.

Và không, tôi không nghĩ rằng anh ấy đang sử dụng phiên bản Ruby cũ hơn.

35 hữu ích 5 bình luận chia sẻ
15

Dòng mã

puts man.noise=("Howdie!")

KHÔNG sử dụng phương thức getter, vì vậy phương thức getter không cần phải được xác định để nó hoạt động. Dòng đó chỉ sử dụng phương thức setter. Giá trị trả về của phương thức setter tự động bằng bất kỳ giá trị nào nằm ở phía bên phải của dấu bằng, vì vậy "Howdie!" được chuyển đến puts.

Dòng mã

puts man.noise

KHÔNG sử dụng phương thức getter và nó sẽ không hoạt động nếu bạn loại bỏ phương thức getter.

15 hữu ích 5 bình luận chia sẻ
5

Chắc chắn cả hai đều trả về một giá trị, nhưng hành vi của chúng khác nhau.

Giả sử đã có một thành viên @a .

với getter, người ta nhận được giá trị hiện tại @amà không cần sửa đổi nó.

với setter, một người sẽ sửa đổi @avà lấy giá trị mới của nó làm giá trị trả về.

khi nghĩ về hành vi của người định cư, hãy lưu ý:

  1. giá trị cũ của @a không thể lấy được bằng setter và đã bị ghi đè.

  2. những gì trả về bởi setter , thực sự đã được biết trước khi gọi setter.

5 hữu ích 1 bình luận chia sẻ
1

Có thể là sự chú ý đối với getters và setters là vì một số ngôn ngữ khác cho phép bạn truy cập trực tiếp vào các biến lớp. Python:

class k:
    i = 100

print k.i # 100
k.i = 200
print k.i # 200

Ngược lại, Ruby giữ tất cả các biến của nó hoàn toàn riêng tư đối với lớp và chỉ hiển thị chúng thông qua các phương thức của trình truy cập.

Trong ví dụ của bạn, nếu bạn loại bỏ getter, bạn thực sự có thể tương tác với biến (nghĩa là: thay đổi nó) qua setter, nhưng bạn không thể lấy lại (theo cách thường xuyên) khi bạn cần.

1 hữu ích 0 bình luận chia sẻ
loading
Không tìm thấy câu trả lời bạn tìm kiếm? Duyệt qua các câu hỏi được gắn thẻ ruby , hoặc hỏi câu hỏi của bạn.

Có thể bạn quan tâm

loading