2016-11-21 22 views
0

我目前困惑,我不知道什麼時候應該調用get方法。當我沒有得到我的變量並且如果我用get調用它時,有什麼區別。我知道「這」是什麼,但我不確定調用方法和調用變量是否有區別。 例如:java中的this.variable和this.getVariable()有什麼區別?

public class Student() { 
    private int idNumber; 
    private String name; 
    Student (int idNumber, String name) { 
     this.idNumber = idNumber; 
     this.name = name; 
     } 
     public int getIdNumber() { 
     return idNumber; 
     } 
     public String getName() { 
     return name; 
     } 
     // method to add 2 idNumbers 
     public int addNumbers(int no) { 
     int result = this.idNumber + no; 
     int result = this.getIdNumber() + no; 
     } 

是否有區別,如果我叫get方法,而不是變量本身在這種情況下? 非常感謝您的提前.`

+1

'this.variable'指當前對象中的字段。 'this.getVariable()'是一個函數調用。 – mallaudin

+1

@bradimus我不認爲這是重複的。引用的問題詢問了關於getter和setters的這個_outer_世界。這個問題反而提出了使用getter(或不)的方法_side_同一個類。 – Seelenvirtuose

+0

問題是重複的。在參考的問題中沒有提到它只應用於「外部世界」。兩種情況適用相同的規則。 –

回答

-1

該類的成員變量是私人的,所以他們不能在類之外使用。對於外部世界,您需要使用getVariable(),但在類的內部,在成員方法中,可以直接引用該變量。

這就是被稱爲「encapsulation」,並且是面向對象編程的基本組成部分之一(連同多態和繼承)

+0

爲什麼downvote?這個答案中有沒有不正確的地方? –

0

是否有區別,如果我叫get方法,而不是變量 本身在這種情況下?

沒有差別,但是,代碼將更加可讀如果直接使用this.idNumber而不是訪問使用該方法this.getIdNumber()可變訪問變量。如果代碼是可讀的(這很重要),那麼您可以更好地理解它並輕鬆維護它。

0

this.variable是對變量本身的直接引用。 this.getVariable()是一種方法,雖然它可能只會給你this.variable作爲結果,它可能會做其他任何事情。這只是一個變量。

這有一些用途。當談到獲得者時,我喜歡在防守方面進行編程。

例如,假設我們有以下類結構。

public class School { 
    private final Set<Person> teachers = new HashSet<>(); 

    public boolean addTeacher(Person teacher) { 
     return teachers.add(teacher); 
    } 
} 

現在,我們想要的功能,使其回到設定教師的學校。這可能是誘人的...

public Set<Person> getTeachers() { 
    return this.teachers; 
} 

...但這可能會有一些意想不到的後果。例如,如果你的類的一個客戶端做這個...

Set<Persons> persons = someSchool.getPersons(); 
persons.clear(); 

...然後突然你的內部人士集已清空!這可能是意外的行爲,暴露給你的班級的客戶(我有幾個IRL專業案例,發生這種情況!)。答案是不會給你的用戶訪問你的內部,私人對象,通過實施以略微不同的方式getTeachers() ...

public Set<Person> getTeachers() { 
    return new HashSet<Person>(this.teachers); 
} 

現在,getTeachers方法將返回一組全新的人的。無論用戶對getTeachers的結果如何,私人收藏(this.teachers)都不能通過對集合進行修改來修改。這使學校班級能夠更好地控制其內部狀態,並且是「吸氣劑」未返回其「正在獲得」的實際變量時的一個很好的例子。

0

的區別是什麼,當我打電話給我的變量沒有得到,如果我把它弄...

一般來說,如果你正在談論的類中訪問屬性,有差不多沒有區別,因爲您仍在訪問相同的屬性。

但是仍然存在一個細微的差別,我會在稍後回到這一點。

現在,如果您是從課外訪問屬性。如果標記爲private訪問修飾符,您將無法訪問該屬性。

例子:

class Hero{ 
    private int health;  //inaccessible from anywhere outside the class 

    public int getHealth(){ 
     return health;  //allows access of health outside the class 
    } 
} 

現在想象一下,如果health被宣佈爲公共的和你只是直接訪問它使用myHero.health有一天你意識到你需要的health數據類型更改爲其他這樣的東西作爲一個類來表示健康:

class Health{ 
    private int minHealth; 
    private int maxHealth; 
    private int healthValue; 
} 

但是你已經有myHero.health如此頻繁,你AR編碼e現在無法更改您的代碼。

現在,想象一下如果您一直在使用myHero.getHealth()進行編碼。它現在會有所作爲,因爲所有的代碼都可以繼續使用getHealth()獲取健康值的getter。所有你需要做的是改變getHealth()實施返回生命值:

class Hero{ 
    private Health health;  //Data type changed, no worries.. 

    public int getHealth(){ 
     return health.getHealthValue(); //Implementation can be changed here..   
    } 
} 

health數據類型可以沒有太多的後顧之憂改變(在其他模塊方面直接依賴於它)。由於它是private,它不依賴於它,我們可以改變它,而沒有太多的副作用。


現在回去談談類內部訪問該屬性。就我個人而言,我認爲調用getter而不是直接訪問屬性仍然是安全的。

使用下面的例子:

class Circle{ 
    private double radius; 
    private double area; 

    public double getArea(){ 
     return Math.PI * radius * radius; 
    } 
} 

這不是一個很好的設計,但爲了解釋的緣故,我已經寫了這種方式。

所以在類Circle本身,似乎this.areathis.getArea()做同樣的事情。但在某些場合中,吸氣劑本身可不止只是一個傳遞你的裸體變量做工作。寫this.area可能給你0.0,而不是基於半徑的區域的傾向。

再次,不是最好的例子,但你明白我的意思..

0

一類新MyClassA有領域,最好的做法是: - 在和領域

在這種情況下添加公共getter和setter方法是設定值,每個字段並獲得價值 - 增加私人領域 ,當你實例化一個新MyClassB例如包含MyClassA實例的時候,你的myClassB對象只能使用getters和setter,並且不能直接與MyClassA字段交互。

這個優點就是例如在將值存儲在myClassA之前檢查值的可能性。

在您的例子,如果你想要的ID號不能爲負,使用此setter:

public void setIdNumber(int newValue) { 
    if(newValue<0) { 
     this.idNumber=newValue*-1; 
    } else { 
     this.idNumber=newValue; 
    } 
} 

的其他優勢,使用getter和setter方法是你可以鎖定現場讀取或從外部對象寫。你只需要寫入getter的代碼,以允許讀或者設置器允許寫入。

而私人領域與getter/setters一起使用的最後一個要點是,所有使用反射動態讀取/寫入未知對象的庫都使用這些getters/setters。通過反射,您可以獲得任何對象(私有或公共)的字段列表以及用於讀/寫的對象列表,您必須爲名爲「myField」的字段調用「getMyField」/「setMyField」(add get/set和上面的第一個字母)

我知道的最好的例子是序列化!它允許你轉換任何對象的字節序列,以便將其存儲在數據庫或文件中。然後你可以讀取這個序列並反序列化,以便在原點的相同狀態下再次獲取對象。而且只有一條指令:)

+0

「所有使用反射來動態讀取/寫入未知對象的庫都使用這些獲取器/設置器。」這不是真的。反射時不需要Getters/Setter,很多庫不需要它們,或者可以配置字段訪問等。序列化與getter和setter完全不相關,它是一個完全不同的機制,可以訪問所有數據沒有問題。 – Kayaman

+0

謝謝Kayaman的澄清...所以我所有的解釋都不好:p(對不起) – Elloco

相關問題