2013-07-22 3 views
0

При разработке моего последнего проекта я обнаружил что-то, что нарушает правила инкапсуляции и видимости, когда я их понимаю.Изменение членов частного поля без использования сеттера

В моем классе GUI я создал несколько переменных класса для текстовых полей и кнопок в приложении и установил, что все они являются частными. Я также установил getters для кнопок и текстовых полей, которые возвращают значения частных членов. В моем классе SqlStatements я ссылаюсь на геттеры, а затем вызываю метод setText() на геттерах и изменяет значение полей частного члена. Как это возможно?

Например:

public class InitGUI { 
    public static JTextField getfNameField() {  <---- getter for JTextField 
     return fName; 
    } 

    private static JTextField fName; <---- JTextField variable. 
} 

public class SqlStatements { 
    // how is this able to change the value of a private member? 
    InitGUI.getmNameField().setText(""); 
} 
+0

Возможно ли это? – PSR

+0

, предоставляющий доступ к закрытому члену с помощью метода, не сохраняет его закрытым. Если это имеет смысл. – Breavyn

+0

Я думал, что за пределами использования геттера и или сеттера в частном члене его нельзя трогать извне класса. – Keith

ответ

11

Вы путаете неизменность с видимостью. Предоставляя getter для частного поля (вы нарушаете инкапсуляцию), вы раскрываете его методы внешнему миру. (возможно, некоторые методы, которые изменяют внутреннее состояние полей - и, как следствие, ваш класс).

+0

Я думал, что, не предоставив метод setter для частного текстового поля, они не будут модифицироваться вне класса. – Keith

+2

@ Keith: re, '« Я думал, что ... »« Мы все ошибаемся, и теперь вы знаете лучше. Лучше всего было бы дать вашему классу 'public void setFNameText (String text)' method и 'getFNameText()', который предотвращает прямое воздействие компонента Swing. –

+0

Думаю, я понимаю, что вы имеете в виду. Делая это так, как я это сделал, я обнаружил объект TextField и не изменяю значение в поле частного члена? – Keith

2

Каким образом это может изменить значение частного участника?

Это не изменения значения частного поля fName - то есть еще ссылка на тот же JTextField. Все, что вы делаете, это вызов метода на этом объекте JTextField.

+0

Итак, что было бы целью использования частного для члена поля, если вы можете выполнять прямые манипуляции на нем? – Keith

+0

Keith, если вы создаете неизменяемый класс и используете его как частное поле, и вы предоставляете его для этого, вы не можете «выполнять прямые манипуляции» на нем. Надеюсь, вы медленно догадались. :) – gyorgyabraham

0

Целью геттеров и сеттеров является предоставление ограничений или запретов на внесение изменений в частные переменные .

Если это не полезно для вас, нет необходимости определять их как Private

0

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

public class InitGUI { 
    public static JTextField getfNameField() {  <---- getter for JTextField 
     return fName; 
    } 

    private static JTextField fName; <---- JTextField variable. 
} 

public class SqlStatements { 
    // how is this able to change the value of a private member? 
    InitGUI.getmNameField().setText(""); 
} 

Вы лучше делать:

public class InitGUI { 
    // for heaven's sake, get rid of the statics!  
    private JTextField fName= new JTextField(10); 

    public String getfNameText() {  
     return fName.getText(); 
    } 

    public void setfNameText(String text) { 
     fName.setText(text); 
    } 

} 

Это позволит ограничить воздействие ваших компонентов только экспозиции, которые вы хотите.

И снова, пожалуйста, избегайте использования статического ненужного использования.

+0

Можете ли вы объяснить мне, почему использование статических методов в этом случае плохо? Должен ли я просто пытаться передать объект в качестве параметра? – Keith

+0

@Keith: использование статических разрывов объектно-ориентированной парадигмы, потому что вы больше не имеете дело с экземплярами, а с классами. Ваш код становится сложнее обновлять и отлаживать, и вы не можете использовать модульное тестирование на нем. Нет смысла использовать объектно-ориентированный язык статическим образом, так как вы будете использовать более 80% мощности языка, делая это. –

0

Вы смущены тем, как члены работают в java. Частный член действительно является частным для начала. Когда вы предоставляете доступ к этому элементу через метод getter, он действительно может быть «изменен». Геттер возвращает экземпляр class, хранящийся в элементе. Независимо от того, что вы делаете с этим экземпляром, это влияет на частную переменную, поскольку они оба одинаковы: экземпляр.

Однако он не возвращает memory address, что этот элемент хранится на. Из-за этого вы не можете заменить экземпляр, выполнив;

JTextField field = InitGUI.getmNameField(); 
field = new JTextField(); // this can't affect the original. 

Это сообщение Is Java "pass-by-reference" or "pass-by-value"? может помочь объяснить ссылку в Java по ценности природы.

0

Вы можете предоставить публичные геттеры для определенных полей JTextField, а не для получения всего объекта. Таким образом вы можете избежать того, чтобы кто-то установил поля.

например.

public String getFname(){ 
return fName.getXXXX(); 
} 
Смежные вопросы