2010-07-17 93 views
7

每次我寫一些簡單的getter(獲取剛剛返回成員值的函數)我想知道爲什麼oop語言只有一個「只讀」訪問修飾符,它允許讀取對象成員的值,但不允許你像C++中的const事物那樣設置它們。爲什麼oop語言沒有「只讀」訪問修飾符?

私有的,受保護的公共訪問修飾符爲您提供完整(讀/寫)訪問權限或無權訪問權限。

編寫一個getter並每次調用都很慢,因爲函數調用比訪問成員要慢。一個好的優化器可以優化這些getter調用,但這是'魔術'。我不認爲學習某個編譯器的優化器如何工作並編寫代碼來利用它是不錯的主意。

那麼,爲什麼我們需要編寫訪問器,在實踐中隨處可用的只讀接口,只需要一個新的訪問修飾符就可以實現這個功能?

ps1:請不要告訴'它會破壞封裝'。一個公衆foo.getX()和一個公開的但只讀foo.x會做同樣的事情。

編輯:我沒有寫清楚我的帖子。抱歉。我的意思是你可以在外面讀取會員的價值,但是你不能設置它。您只能在類作用域中設置它的值。

+4

你的ps1假定一個Property Getter總是簡單地封裝一個字段變量,但並非總是如此。例如,屬性getter可能是一個包含多個字段,字段連接等的計算。屬性getter封裝了邏輯,因此可以輕鬆更改內部實現。 – 2010-07-17 11:12:41

+0

爲了迴應您的編輯,Marcelo Cantos的答案或我的將完全適合您的需求。 – BoltClock 2010-07-18 13:13:25

回答

11

您錯誤地從一種或一些OOP語言(一般或多種)推廣到OOP語言。實現語言的一些例子只讀屬性:

  • C#(感謝,達林和託尼奧)
  • 德爾福(= Object Pascal中)
  • 紅寶石
  • 斯卡拉
  • 的Objective-C(感謝,Rano)
  • ...更多?

就我個人而言,我討厭Java沒有這個(但?)。看過其他語言的功能後,Java中的樣板文字看起來很乏味。

+1

Java的「最終」計數? – BoltClock 2010-07-17 11:14:29

+1

@BoltClock:好點,但最終字段與只讀屬性的語義並不完全相同。後者通常會讓班級成爲私人後門,以改變基礎價值,同時保持封裝對外的安全,這可能是一個很好的收益。 「最後」是......最終。 – 2010-07-17 12:02:24

+0

如果Java的'final'不算,那麼Scala的'val'也不應該算在內。 – missingfaktor 2010-07-17 16:13:25

0

C#屬性允許輕鬆定義只讀屬性。請參閱article

2

C#有readonly,Java和其他一些人有final。您可以使用它們使您的成員變量爲只讀。

在C#中,您可以爲屬性指定一個getter,使其只能被讀取,而不能被更改。

private int _foo; 

public int Foo 
{ 
    get { return _foo; } 
} 
+2

public int Foo {get;私人設置;}是實現這一目標的另一種方式。沒有附加聲明 – btlog 2010-07-17 11:10:33

2

其實不,他們是不一樣的。公開foo.getX()仍然允許內部類代碼寫入變量。對於內部類代碼,只讀foo.x也是隻讀的。

還有一些語言確實有這樣的修飾語。

+0

它看起來在C#中只讀意味着您仍然可以修改該類中的變量,但從外部它只是只讀的(http://msdn.microsoft.com/zh-cn/library/acdd6hb7%28VS.71 %29.aspx)。 – Frank 2010-07-17 13:35:42

+1

C#只讀字段只能在聲明或構造函數中分配一次。 – 2010-07-17 18:02:42

5

在C#中,您可以在設定的定義有不同的訪問預選賽自動財產,並得到:

public int Foo { get; private set; } 

這樣,類實現可與物業其心臟的內容修修補補,而客戶端代碼可以只讀它。

0

在Delphi:

strict private 
    FAnswer: integer; 
public 
    property Answer: integer read FAnswer; 

聲明訪問私有字段FAnswer一個只讀屬性答案。

0

這個問題主要歸結爲:爲什麼每種語言都不像C++那樣具有const屬性?

這就是爲什麼它是不是在C#:

安德斯·海爾斯伯格:是的。關於 const,很有意思,因爲我們 也一直聽到這種抱怨: 「爲什麼你沒有const?」隱含的 在問題是,「爲什麼你不 有常量,由 運行時強制執行?」這真的是人們所要求的,儘管他們不會來 並且這樣說。

const在C++中工作的原因是 ,因爲您可以將其強制轉換。如果你 不能丟棄它,那麼你的世界 會吸。如果你聲明一個採用const Bla的方法 ,你可以通過 它是一個非常量的Bla。但如果是其他方式 你不能。如果 聲明瞭一個採用非常量Bla的 的方法,則無法將它傳遞給一個 const Bla。所以現在你被卡住了。所以你 逐漸需要一個常量版本 所有不是常量,而你 結束了一個影子世界。在C++中,你使用 就可以避開它,因爲和C++中的 一樣,它純粹是可選的 ,不管你是否需要這個檢查。 如果你不喜歡它,你可以將其強行移開 。

參見:http://www.artima.com/intv/choicesP.html

所以,究其原因WY常量在C++的工作原理是,因爲你可以解決它。對於C++來說,這是明智的做法,它的根源在C.對於像Java和C#這樣的託管語言,用戶會希望const會像垃圾收集器一樣安全。這也意味着你無法解決這個問題,如果你無法解決這個問題,它將毫無用處。

+0

那傢伙顯然不知道C++。確實,你可以拋棄const,但實際上這樣做真的很難得。 – Puppy 2010-07-17 13:29:35

+0

@DeadMG:如果我在谷歌代碼搜索中搜索,我會爲const_cast獲得32000個點擊量。作爲一個基準:dynamic_cast獲得近60000.所以它不僅僅是我和安德斯認爲他們需要const_cast。 – 2010-07-17 16:31:03

+0

需求不等於需要關於它的信息,或者當你不需要時,認爲你需要它。搜索引擎中的結果數量是一個非常非常不相關的指標。如果你弄清了500萬行代碼並發現它經常發生,那就不一樣了。 – Puppy 2010-07-17 20:51:10