2009-09-23 36 views
6

Trước đây tôi đã nghĩ rằng một thuộc tính trong Groovy được chỉ ra bởi sự thiếu sót của một từ khóa phạm vi. Nói cách khácĐịnh nghĩa thuộc tính Groovy

class Test { 
    def prop = "i am a property" 
    public notProp = "i am not" 
} 

Tuy nhiên, dường Tôi không chính xác về vấn đề này, bởi vì các bản in kịch bản sau "getter val"

class Foo { 
    public bar = "init val" 

    public getBar() { 
    "getter val" 
    } 
} 

println new Foo().bar 

Thực tế là getter được gọi khi bar được truy cập cho thấy rằng bar là một tài sản chứ không phải là một lĩnh vực. Vậy chính xác là sự khác nhau giữa các trường và thuộc tính trong Groovy.

Cảm ơn, Don

Trả lời

3

Để truy cập vào một lĩnh vực trực tiếp bạn phải thêm vào trước nó với một dấu @:

assert "getter val" == new Foo().bar 
assert "init val" == new Foo()[email protected] 

Đó là dạng viết tắt của new Foo().getBar() công trình, mặc dù bar không phải là một tài sản, vẫn còn ngắn gọn từ quan điểm của tôi.

Ngược lại bạn không thể thực hiện cuộc gọi đến foo.setBar("setter val"), nhưng bạn có thể trong trường hợp bạn đã xác định bar làm thuộc tính mà không có công cụ sửa đổi truy cập.

1

Sử dụng công cụ sửa đổi thực sự ngăn chặn việc tạo thuộc tính. Điều làm bạn khó hiểu là . dường như dự phòng khi truy cập trường khi không có thuộc tính nào tồn tại.

 
$ groovysh 
Groovy Shell (2.1.0, JVM: 1.7.0_21) 
Type 'help' or '\h' for help. 
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
groovy:000> class A { def a = "foo" }; 
===> true 
groovy:000> new A().getA() 
===> foo 
groovy:000> new A().a 
===> foo 
groovy:000> new A().properties 
===> {class=class A, a=foo} 

Nhưng:

 
groovy:000> class A { public def a = "foo" }; 
===> true 
groovy:000> new A().getA() 
ERROR groovy.lang.MissingMethodException: 
No signature of method: A.getA() is applicable for argument types:() values: [] 
Possible solutions: getAt(java.lang.String), grep(), grep(java.lang.Object), with(groovy.lang.Closure), putAt(java.lang.String, java.lang.Object), wait() 
     at groovysh_evaluate.run (groovysh_evaluate:2) 
     ... 
groovy:000> new A().a 
===> foo 
groovy:000> new A().properties 
===> {class=class A} 
0

Tôi nghĩ @Christoph Metzendorf câu trả lời là đúng ...

Để truy cập vào một lĩnh vực trực tiếp bạn phải thêm vào trước nó với một @ dấu :

assert "getter val" == new Foo().bar 
assert "init val" == new Foo()[email protected] 

... nhưng tôi sẽ thêm điều đó vào ví dụ Foo của bạn, phương pháp getBar của bạn đã vượt qua phương thức getBar mà Groovy đã tạo cho bạn. Bạn có thể sử dụng cú pháp trên để truy cập trực tiếp bar nếu bạn muốn tiếp tục ghi đè phương thức mặc định getBar Groovy được tạo cho bạn hoặc bạn không thể ghi đè getBar để mọi cuộc gọi đến getBar sẽ sử dụng trình tạo Groovy được tạo cho bạn.

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