2016-12-31 24 views
0

我們可以通過訪問方法,例如訪問私有數據成員如果我們可以使用訪問器訪問私有數據成員,而不是訪問私有方法的原因?

private int num=5; 

public int get_num() 
{ 
    return num; 
} 

,我們可以從即使num是私有數據成員的任何類訪問返回值。

所以類似的說明我們不能創建accessor方法返回私有方法嗎? 我只是有一個想法,如果我們不能這樣做,請解釋。謝謝

+1

第一點是語言是如何定義的。至於第二點:當然可以。只需創建一個公共適配器方法。雖然我想知道這樣做是否合理,但考慮到封裝方法並不合理。 – Paul

回答

2

您可以通過公共方法訪問私有方法。這有時用於包裝複雜的私有方法並公開更簡單的公共API。

class Delegator { 

    private void doPrivateStuff(int param) { ... } 

    public void doStuffOnce() { 
     doPrivateStuff(1); 
    } 

    public void doStuffIfConditionIsMet() { 
     if(condition) { 
      doPrivateStuff(1); 
     } 
    } 
} 

您還可以使用反射訪問私有方法。 http://tutorials.jenkov.com/java-reflection/private-fields-and-methods.html

1

因爲訪問者是公開的,它可以從課外訪問;即使它返回私人數據。

返回數據的訪問修飾符不相關,只有方法的訪問修飾符很重要。

如果您創建了一個返回對私有方法的引用的公共方法,那麼您可以在類之外調用私有方法。但這完全違背了使該方法保密的目的。

你好,我想知道「爲什麼讓一個公共的getter到一個私有變量」。答案是,雖然有可能檢索的私人數據,但它是不可能的(除非你創建一個公共數據)以更改的公共數據。這假設私人日子是不變的。如果它是可變的,那麼重新調用對私有數據的引用就會否定從變量私有中獲得的任何保護。

3

重構代碼時會創建私有方法。他們是實施細節,外界沒人需要知道。它們用在公共方法內部,它們應該提供你想要提供給你的客戶端的功能(每個公共方法可以被稱爲一個由其他類,即它的客戶端使用/使用的API)。

提供訪問修飾符來幫助您實現正確的抽象。所以標記爲私人的東西只能在你的班級內部直接訪問。但是,如果你想讓外面的人讀取/寫入它的值,你可以通過getters/setter公開它。同樣,私人方法在班級以外是不可訪問的。但是沒有人阻止你創建只調用這個私有方法的公共方法。這樣你就可以訪問私有方法。但這將是一個非常糟糕的設計。

1

TL; DR

訪問私有方法違反了encapsulation基本面向對象的原則。問題不是「我們可以訪問私人方法嗎?」但「我們是否應該這樣做?」。它與信息隱藏的原理相矛盾,並且它將合同打破爲客戶「提供」給消費者。強制你這樣做的對象或類應該被認爲設計得不好。

爲什麼你不應該訪問私有成員

首先一類應該實現你的域邏輯的一部分,是密切相關,有必要與外界履行其職責交往較少(這被稱爲高凝聚力)。然後爲您的類/對象定義一個公開接口,其中包含您公開給外部世界的功能 - 對象的使用者只能使用此接口(稱爲鬆耦合)。

私有方法可以被看作是以更好的可讀方式在你的類內部構造代碼的一種方式 - 它們不打算與外部世界共享。將它們視爲班級開發人員在不違反合同的情況下進行隨意更改的「安全空間」。這就是爲什麼如果你實際訪問私有方法會產生不良的副作用的原因:你的代碼可能會破壞它,類的開發者決定改變這種方法的實現。 Effective Java, Chapter 4, Item 13解釋這爲protected成員:

對於公共類的成員,當訪問級別,從包私人去保護髮生在無障礙的大幅增加。受保護的成員是該類導出的API的一部分,並且必須永久支持。另外,導出類的受保護成員表示對實現細節的公開承諾。

例外

我從「沒有訪問對象之外的私有成員」的規則所知道的唯一的例外是在測試中,當你要麼需要重新設置一個特定的變量(例如一個Singleton)或者你想通過測試實現的私有部分來促進複雜邏輯的測試,從而降低測試的複雜性。

+0

如果我們可以使用反射訪問類之外的私有方法,那麼安全性如何?我的意思是如果我們可以使用xyz技術訪問私有方法,則不安全,因爲我們可以使用某種技術來克服安全性 –

+0

我不會考慮訪問像私人安全措施一樣的修飾語。這是一種以標準方式限制消費者訪問代碼的某些部分的方法。如果您有權訪問代碼級別的功能,則無論如何都不能「保證」安全性。 –