Trong Scala, khi bạn viết một var foo
, trình biên dịch Scala tự động tạo ra một setter (gọi tắt là foo_=
) và một getter (được gọi là foo
) cho nó và đặt trường là riêng tư (bạn sẽ thấy trường đó là riêng tư nếu bạn dịch ngược một lớp có các trường Scala 'công khai' với javap
). Đó là ý nghĩa của phương thức 'foo_ = ghi đè không có gì'. Trong đặc điểm của bạn, bạn chưa xác định phương thức foo_=
và đối với bộ tách trường công cộng và getters luôn là sẽ ghép đôi.
Nếu bạn không cung cấp giá trị mặc định trong đặc điểm (nghĩa là phương pháp trừu tượng), thì từ khóa override
là không cần thiết. Vì vậy, trong ví dụ đầu tiên của bạn, getter ghi đè phương thức trừu tượng và setter ... nó chỉ ở đó. Trình biên dịch không phàn nàn. Nhưng khi bạn cung cấp một thực hiện thực tế của phương pháp trong đặc điểm, bạn cần phải ghi rõ từ khóa override
khi ghi đè. Khi viết protected var foo
, bạn chưa chỉ định từ khóa override
cho trình lấy và khi viết override protected var foo
, bạn cũng đã chỉ định cho trình biên dịch rằng phương thức foo_=
sẽ bị ghi đè, nhưng đặc điểm này không có phương pháp như vậy.
Ngoài ra, về mặt logic, bạn không thể ghi đè một số def
với số var
(xem xét chế độ ghi đè nghiêm ngặt, như trong đoạn trước). Một def
là một hàm hợp lý (bạn cung cấp cho nó một số đầu vào, nó tạo ra một đầu ra). Một var
tương tự như một hàm không có arg, nhưng cũng hỗ trợ thiết lập giá trị của nó cho một cái gì đó khác, một hoạt động không được hỗ trợ bởi một hàm. Thay vào đó, nếu bạn thay đổi nó thành val
, điều đó sẽ ổn thôi. Nó giống như một hàm luôn tạo ra cùng một kết quả (được lưu trữ).
Nếu bạn muốn có hành vi tương tự như một var
bạn có thể làm một cái gì đó như thế này (bằng cách setter rõ ràng và thu khí):
class Wibble extends SomeTrait {
private var bar = "Hello"
override protected def foo = bar
protected def foo_=(v: String) { bar = v}
}
Bây giờ bạn có thể làm bất cứ điều gì bạn có thể làm với một var :).
val x = new Wibble
println(x.foo) // yields "Hello"
x.foo = "Hello again"
println(x.foo) // yields "Hello again"
Nguồn
2009-09-08 11:08:13
Rất tiếc - Tôi đã xảy ra lỗi - phương pháp tính trạng gốc cũng phải được bảo vệ. Tôi không chắc tôi đồng ý với bạn về mặt logic không thể ghi đè 'def' bằng' var'. Tất cả 'def' của tôi là nói rằng tôi mong đợi có một accessor gọi là' foo' trả về một String - khai báo 'var' là một sự thực hiện của điều này –
Tôi nghĩ rằng tôi đồng ý với bạn. Tôi đã nghĩ về việc ghi đè như một khái niệm chặt chẽ hơn khi tôi viết câu trả lời. Tôi sẽ chỉnh sửa câu trả lời và cung cấp giải pháp khả thi :). –
Đó là một sự xấu hổ không có một cú pháp 'override def as var' –