java - programming中文 - 您將如何從對象方法中訪問對象屬性?




polymorphism (12)

從不是getter / setter方法的對象方法中訪問對象屬性的“純粹”或“正確”方法是什麼?

我知道從對像外部您應該使用getter / setter,但是從內部您只需要這樣做:

Java:

String property = this.property;

PHP:

$property = $this->property;

還是你會做:

Java:

String property = this.getProperty();

PHP:

$property = $this->getProperty();

原諒我,如果我的Java稍微有些落後,那距我用Java編程已有一年了...

編輯:

似乎人們以為我只是在談論私有或受保護的變量/屬性。 當我學習面向對象時,我被教導即使每個屬性都是公共的,也要對每個屬性都使用吸氣劑/設置器(實際上,我被告知永遠不要公開任何變量/屬性)。 因此,我可能一開始就從一個錯誤的假設開始。 似乎回答這個問題的人可能是在說您應該擁有公共財產,而那些人不需要吸氣劑和塞子,這與我所教的內容和我所談論的內容背道而馳,儘管也許需要討論以下內容:好。 不過,這可能是另一個問題的好話題...


我只是在這裡落水嗎?

也許 ;)

另一種方法是利用私有/受保護的方法來實際進行獲取(緩存/ db / etc),並使用一個公共包裝器來增加計數:

PHP:

public function getName() {
    $this->incrementNameCalled();
    return $this->_getName();
}

protected function _getName() {
    return $this->name;
}

然後從對象本身內部:

PHP:

$name = $this->_getName();

這樣,您仍然可以將第一個參數用於其他內容(例如發送標誌,以了解此處是否使用了緩存的數據)。


PHP提供了多種方法來處理此問題,包括魔術方法 __get__set ,但我更喜歡顯式的getter和setter。 原因如下:

  1. 可以將驗證放置在setter(以及與此相關的getter)中
  2. Intellisense使用顯式方法
  3. 毫無疑問,屬性是只讀,只寫還是讀寫
  4. 檢索虛擬屬性(即計算值)看起來與常規屬性相同
  5. 您可以輕鬆地設置一個從未在任何地方定義的對象屬性,然後該屬性將不再記錄

好吧,似乎有了C#3.0屬性的默認實現,該決定就由您決定; 您必須使用(可能是私有的)屬性設置器來設置屬性。

我個人僅在不使用私有成員的情況下使用,否則會導致對象處於不太理想的狀態,例如在初始化時或在涉及緩存/延遲加載時。


如果我不編輯該屬性,除非有特殊情況(例如另一個對象內部的MySQLi對象 get_property() 否則我將使用 get_property() 公共方法,在這種情況下,我將僅公開該屬性並將其稱為 $obj->object_property

在對象內部,對我來說,始終是$ this-> property。


就個人而言,我覺得保持一致很重要。 如果有getter和setter,請使用它們。 我唯一直接訪問字段的時間是訪問器的開銷很大。 看起來您好像不必要地膨脹了代碼,但將來肯定可以省去很多麻煩。 經典示例:

稍後,您可能希望更改該字段的工作方式。 也許應該即時計算,或者您想為後備商店使用其他類型。 如果您直接訪問屬性,則這樣的更改可能會使大量代碼中斷。


我可能是錯誤的,因為我是自動編輯的,但是我從不在Java類中使用公共屬性,它們始終是私有的或受保護的,因此外部代碼必須由getter / setter進行訪問。 更好地用於維護/修改目的。 對於內部類代碼...如果getter方法很簡單,那麼我直接使用該屬性,但是我始終使用setter方法,因為如果願意,我可以輕鬆地添加代碼來引發事件。


我對使用 gettersgetters 的優良 getters 感到一致感到驚訝。 我建議艾倫·霍魯布(Allen Holub)撰寫的煽動性文章“ 吸氣吸毒者和邪惡的吸毒者 ”。 誠然,標題是為了震撼價值,但作者提出了有效的觀點。

本質上,如果每個私有字段都有 getterssetters ,那麼您 getters 這些字段與公共字段一樣好。 您很難改變私有字段的類型,而不會對調用該 getter 每個類產生連鎖反應。

而且,從嚴格的面向對象的角度來看,對象應該響應與其(希望)單一職責相對應的消息(方法)。 絕大多數的 getterssetters 對其組成對像沒有意義; Pen.dispenseInkOnto(Surface) 對我而言比 Pen.getColor() 更有意義。

Getter和Setter還鼓勵該類的用戶向對象詢問一些數據,執行計算,然後在該對像中設置其他值,這被稱為過程編程。 最好只是簡單地告訴對像要做您打算做的事情。 也稱為 信息專家 習慣用法。

但是,getter和setter是在層邊界上必不可少的弊端-UI,持久性等。 限制對類內部的訪問,例如C ++的friend關鍵字,Java的程序包保護的訪問,.NET的內部訪問以及 Friend Class Pattern, 可以幫助您減少 getters 和setter的可見性,使其僅針對需要它們的人。


我必須在這裡遺漏一點,為什麼要在對象內使用吸氣劑來訪問該對象的屬性?

得出結論,吸氣劑應稱為吸氣劑,吸氣劑應稱為吸氣劑。

因此,我想說一個對象方法內部直接訪問屬性,尤其是看到調用該對像中的另一個方法(無論如何將直接訪問該屬性然後返回它)只是毫無意義,浪費的練習(或者我誤解了這個問題) )。


我發現使用setters / getters使我的代碼更易於閱讀。 我也喜歡其他類使用方法時提供的控件,並且如果我更改屬性將存儲的數據。


正如一些評論中所述:有時應該,有時不應該。 關於私有變量的重要之處在於,您可以在更改某些內容時看到它們被使用的所有位置。 如果您的getter / setter執行了您需要的操作,請使用它。 如果沒關係,您可以決定。

可能出現相反的情況,如果您使用吸氣劑/塞特而有人更改了吸氣劑/塞特,則他們必須分析內部使用吸氣劑和塞特器的所有位置,以查看是否弄亂了某些東西。


這具有宗教戰爭的潛力,但是在我看來,如果您使用的是吸氣劑/塞特劑,則也應該在內部使用它-兩者同時使用會導致維護問題(例如,有人向 需要 特定方法的塞特劑中添加代碼)會在每次設置該屬性時運行,並且在內部設置該屬性而無需調用該setter)。


這取決於。 這比其他任何事情都更是樣式問題,沒有硬性規定。





theory