2016-11-21 1 views
0

В настоящее время я запутался, и я не знаю, когда именно я должен называть метод get. В чем разница, когда я вызываю свою переменную без get и если я вызываю ее с get. Я знаю, что делает это, но я не уверен, есть ли разница между вызовом метода и вызовом переменной. , например:В чем разница между this.variable и this.getVariable() в java?

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 Я не думаю, что это дубликат. В упомянутом вопросе спрашивается о геттерах и сеттерах для мира _outer_. Этот вопрос вместо этого просит об использовании геттера (или нет) _inside_ того же класса. – Seelenvirtuose

+0

Вопрос - это дубликат. В упомянутом вопросе нет упоминания о том, что его следует применять только к «внешнему миру». Те же правила применяются для обеих ситуаций. –

ответ

-1

Переменные-члены класса являются частными, поэтому они не могут использоваться вне класса. Для внешнего мира вам нужно использовать getVariable(), но внутри класса, в методах членов, вы можете напрямую ссылаться на переменную.

Это то, что известно как «encapsulation», и это одна из основных частей объектно-ориентированного программирования (наряду с полиморфизмом и наследованием)

+0

почему downvote? Что-то не так в этом ответе? –

0

Есть ли разница, если я назвал метод прибудете и не переменная сама в этом случае?

Там нет никакой разницы, но, код будет более удобным для чтения, если вы непосредственно получить доступ к переменной, используя 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 так часто, что вы ар у меня возникли проблемы с изменением кода.

Теперь, представьте, если вы кодировали myHero.getHealth(). Теперь это изменится, потому что весь код может продолжать использовать геттер, который равен getHealth(), чтобы получить значение здоровья. Все, что вам нужно сделать, это изменить реализацию getHealth() вернуть значение здоровья:

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

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

Тип данных health может быть изменена без особых забот (с точки зрения других модулей, которые зависят от него непосредственно). Так как это private, нет никакой зависимости от него, и мы можем изменить его, не имея слишком много побочных эффектов.

Теперь возвращаясь к разговору о доступе к атрибуту внутри самого класса. Лично я считаю, что по-прежнему будет безопасно звонить получателю, а не напрямую обращаться к атрибуту.

Используя следующий пример:

class Circle{ 
    private double radius; 
    private double area; 

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

Это не хороший дизайн, но ради объяснения, я написал это так.

Так что в классе Circle, может показаться, что this.area и this.getArea() делает то же самое. Но в некоторых случаях сам геттер может выполнять работу больше, чем просто передавать вам голую переменную. Написание this.area может иметь тенденцию давать вам 0.0 вместо области, основанной на радиусе.

Еще раз, не лучший пример, но вы поняли мою точку зрения.

0

для нового класса MyClassA и там поля, лучшая практика: - добавить частные поля - общедоступная метода получения и установки для каждого поля, которые устанавливают значения и получить значения и от полея

В этом случае , когда вы создаете экземпляр нового MyClassB, например, который содержит экземпляр MyClassA, ваш объект myClassB может использовать только геттеры и сеттеры и не может напрямую взаимодействовать с полями MyClassA.

Примером является, например, возможность проверить значение, прежде чем хранить его в myClassA.

В вашем примере, если вы хотите IDNumber не может быть отрицательным, использовать этот метод установку:

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

Другое преимущество использует сеттер и добытчик это вы можете заблокировать поле для чтения или записей от внешнего объекта , Вам нужно только написать код геттера, чтобы разрешить чтение или сеттер разрешать запись.

И последний важный момент использования частного поля с геттерами/сеттерами состоит в том, что все библиотеки, которые используют рефлексию для динамического чтения/записи в объекте unknow, используют эти геттеры/сеттеры. С рефлексией вы можете получить список полей любого объекта (частного или общедоступного) и для чтения/записи на нем, вам просто нужно вызвать «getMyField»/«setMyField» для поля с именем «myField» (добавить get/set и верхняя первая буква)

Лучший пример, который я знаю, - это сериализация! Он позволяет конвертировать любой объект в последовательность байтов, чтобы сохранить его в базе данных или в файле. И затем вы можете прочитать эту последовательность и десериализовать, чтобы снова вернуть свой объект в том же состоянии происхождения. И из этого только 1 инструкция :)

+0

«Все библиотеки, использующие отражение для динамического чтения/записи в неизвестном объекте, используют эти геттеры/сеттеры». Это не правда. Getters/seters не нужны для отражения, и многие библиотеки им не нужны или могут быть настроены для доступа к полю и т. Д. Также сериализация вообще не связана с геттерами и сеттерами, это совершенно другой механизм и может получить доступ ко всем данным без проблем. – Kayaman

+0

Спасибо Kayaman за разъяснение ... так что все мои объяснения плохие: p (извините) – Elloco

Смежные вопросы