2012-01-24 38 views
8

在類中,變量通常被封裝爲私有的,並且將變量限制到特定範圍允許更好的錯誤控制和更少的錯誤。這是有道理的,因爲一個變量可以被訪問的地方越少,那個變量就會出現一個錯誤的地方越少。然而,我總是看到變量是私有的,然後使用getter和setter函數來檢索該值(有時甚至是指向該變量的指針!)。例如int a是專用於防止公衆訪問,但getA()setA()允許直接訪問它們。通過getter和setter(accessor)函數訪問私有變量有什麼意義?

所以不要把getter函數和setter函數藐視它是私有的嗎?我的意思是訪問器函數的私有變量與公共變量相同,只有訪問它們的代碼發生變化。 (object.variable vs object.getVariable())

是否有一個原因讓變量與訪問函數私有變量?與公開相比有什麼優勢嗎?我一般在談論編程,但大多數是用C語言編寫的(即C,C++,C#,Obj-C)。

+1

這真的取決於語言。在限制性OO語言(C#,Java)中,getters/setters是一種常見的習慣用法,而在像C++這樣的更自由的語言中,它們通常是不好的風格。 –

回答

11

這裏的關鍵詞和標籤是「封裝」。您隱藏了a的詳細信息,但仍然可以使用。我喜歡已經列出的原因,還有更多。這是另一個,你正在調試,你發現a有一個不正確的值。如果a是公開的,您必須檢查每個地方a被訪問。如果a是私人與setter方法,你知道的唯一地方a可能已經改變爲以setA()通話 - 將是把一個斷點的好地方;)

+0

+1調試 –

+0

理解它完美,謝謝:) – fdh

+0

根據處理器(如X86),調試器可以設置一個數據斷點(或跟蹤點)在任何寫入變量,這將完成同樣的事情。 – rcgldr

2

因爲如果您更改了該變量的內部表示形式或想要在設置或檢索時執行更多操作,它將不會中斷使用它的所有其他類(並且如果它是庫,則不必改變你的API)。

這也意味着你可以很容易地設置一個斷點來查看它何時被使用(儘管大多數語言/調試器都有某種類型的數據斷點)。

2

也許你會想在下一個版本的庫中添加一些檢查(或者在有人讀取值時做某些事情),如果變量在當前版本中是公共的,升級庫版本將花費一個大量的工作。

0

類定義的行爲和成員狀態的對象......所以有一個setter和一個getter定義了讓其他人查找/更改對象狀態的類的封裝行爲。

換句話說,差異就像是讓你的鄰居進入你的房子,並採取他想要的東西(讓所有對象公開)......或確保鄰居問我他想要什麼我給他(有一個getter/setter ....)

0

爲什麼需要封裝?爲什麼需要OOP?錯誤的C編程語言能夠做我們今天做的事情嗎?問你這個問題。或者如果你曾經在擁有數百萬行代碼的龐大系統上工作。所有你使用的都是程序中每個模塊可訪問的關鍵數據結構的公共變量。

+0

問題在回答? – manetsus

0

當我開始學習面向對象的編程時,我有同樣的問題,因爲在大多數書籍中,他們只是使變量變爲private並添加公共方法(Getter/Setters)來訪問它們,所以我想如果我可以訪問該變量是通過公開的方法得到的,那麼變量是否是私有的是什麼意思。

我得到答案當我開始實施實際業務應用程序。

讓我們考慮一個班的學生,其包含學生姓名,滾不,3名受試者

標記
Class Student { 

    private int rollno; 
    private int java_marks; 
    private int cpp_marks; 
    private int unix_marks; 
    private int percentage; 


    public int getJava_marks() { 
     return java_marks; 
    } 
    public void setJava_marks(int java_marks) { 
     if (java_marks > 100) { 
      System.out.println("Marks value should be less than 100"); 
      //throw exception 
     } 
     this.java_marks = java_marks; 
    } 
    public int getCpp_marks() { 
     return cpp_marks; 
    } 
    public void setCpp_marks(int cpp_marks) { 
     if (cpp_marks > 100) { 
      System.out.println("Marks value should be less than 100"); 
      //throw exception 
     } 
     this.cpp_marks = cpp_marks; 
    } 
    public int getUnix_marks() { 

     return unix_marks; 
    } 
    public void setUnix_marks(int unix_marks) { 
     if (unix_marks > 100) { 
      System.out.println("Marks value should be less than 100"); 
      //throw exception 
     } 
     this.unix_marks = unix_marks; 
    } 
    public int getPercentage() { 
     this.percentage = (this.cpp_marks + this.unix_marks + this.java_marks) /3; 
     return percentage; 
    } 

    public int getRollno() { 
     return rollno; 
    } 
    public void setRollno(int rollno) { 
     this.rollno = rollno; 
    } 

} 

這裏做的,因爲2個原因

  1. 驗證私有變量: 如果用戶提供無效的值標記然後學生對象不應該創建與無效的數據並拋出適當的錯誤/例外。 在標記爲公共變量的情況下,用戶可以爲它們設置任何值,因此我添加了驗證/安全性以確保創建的severy學生對象具有正確的數據。

  2. 安全 在百分比的情況下,用戶不能設置他自己的百分比。百分比是在內部計算和設置的。這裏我不提供百分比的setter方法,所以用戶只能通過getter方法獲取/讀取百分比值。

這會導致抽象中的安全性僅受限(只讀)訪問類變量。

相關問題