So I have a question on "setter" and "getter" methods and how useful they are or aren't.
Let's say I just write a very basic program like the following:
public class Account
{
String name;
String address;
double balance;
}
Then, let's say I write another class that uses this "Account" class, like the following:
class UseAccount
{
public static void main(String[] args)
{
Account myAccount = new Account();
Account yourAccount = new Account();
myAccount.name = "Blah blah"
}
}
etc., etc.
When I write myAccount.name = "Blah blah"
, I am changing the value of the variable "name" in the "Account" class. I am free to do this as many times as I like with the code written the way it is. It has come to my attention, however, that it's better practice to make the variables in the "Account" class private, and then use "setter" and "getter" methods. So if I write the following:
public class Account
{
private String name;
private String address;
private String balance;
public void setName(String n)
{
name = n;
}
public String getName()
{
return name;
}
}
I can still change the value of the variable "name" by just creating another class that has something like:
class UseAccount
{
public static void main(String[] args)
{
Account myAccount = new Account();
myAccount.setName("Blah blah");
}
}
I don't understand how using this method is any different or is supposed to prevent people form changing the value of a private field. Any help?
Try this Golden Rule of Object Oriented Programming.
1. Create private Instance variables.
2. Create public getters and setters to access those Instance variable.
3. This methodology is called Encapsulation. Though Encapsulation can be used in a different way, that has importance in Design Patterns, Like Those Behaviors which keeps changing must be encapsulated in an Abstract Class or Interfaces.
4. Well now back to the topic of Getter and Setter....
Getter and Setter helps Validating the Input to the Instance Variable.
For eg: Assume i got a method to assign the Age of the Dog, Now the age can NoT be negative, If i dont have setter method, then i will not be able to Validate the Input of age.
private int age;
public void setDogAge(int age){
if (age>0){
this.age = age;
}
else{
System.out.println("Please Enter a Valid Age");
}
}
With trivial accessor methods, there is no difference except style, but you can also execute code with them, for example:
public void setName(String name) {
if (name == null) {
throw new IllegalArgumentException("Name may not be null");
}
this.name = name;
}
You can also return copies from a getter, thus protecting your data:
private List<String> middleNames;
public List<String> getMiddleNames() {
return new ArrayList<String>(middleNames); // return a copy
// The caller can modify the returned list without affecting your data
}
These are just two simple examples, but there are limitless examples of how accessor methods can be used.
It is better to follow a consistent style, so that's why we always use getters/setters - so code this like may be executed if needed.
The advantage of using setters ans getters is that you can include rules for lazy initialization, validation, etc. Also, if you need to implement Java Beans complaint code, you need to follow those rules.
If your code never changes then you're right - there is no difference.
However, code changes a lot. What happens if you need to keep track of who has modified their name?
You would need to have a boolean in the Account class that would change to true whenever the name field has changed.
So now you have to go through every source file and put a
myAccount.nameChanged = true'
under each
myAccount.name = whatever;
So you start having code duplication and the possibility for bugs increases. What happens if I missed a name change?
The best way to counteract this is to have member variables classified as private
.
Your setName code would look something like this:
public void setName(String newName)
{
name = newName;
nameChanged = true;
}
And you don't have to worry about bugs!
This is called Encapsulation
when you are declaring some private instance variables and declaring public getter
and setter method
to access and change the instance variables value.
If you are using these getter and setter methods to access/set instance variables then it grantees that your program would not fail if developer changes the instance variable names.
For example in current version you are using name, address, balance Instance variables and are accessing them without getter and setter methods like myAccount.setName("Blah blah");
but what if next version developer changes instance variable name from name
to userName
in that case user program will break but if you are using getter and setter it would not break as developer would not change getter and setter method name(according to OOPS fundamentals).
You can always develop an application without using getter and setter methods.As you have explained.But using getter and setter is better practice because access modifiers private/public gives you encapsulation which is OOPS feature. You can always write your program without using OOPS features like encapsulation,abstraction,inheritance...but if you write large applications without using you will have trouble in maintaining and would soon realize the importance of these features.
As a matter of fact it doesn't prevent and there's no difference until you change access modifiers for getter/setter methods or add additional logic into them. The latter not always a good idea but sometimes helps, for example updating the name should force updating some cached value or performing some checks as a result. Using getters/setters are a good practice and used in several approaches like POJOs and JavaBeans but if you are not going to add custom logic into getters/setters and are not going to use these approaches you will be satisfied of using direct access to the fields.
One thing I'd like to mention. Using getters/setters you can provide computed at the runtime fields that do not exists persistently in the object. For example your Account
class's object holds birth date and you need to get the age of it.
The java keyword "private" in front of each of the Account class’s field declarations, prevents direct reference to that field. If you put myAccount.name = “whatever” in the UseAccount class, you get the error message: "name has private access in Account". Instead of referencing myAccount.name, the UseAccount programmer need to call method myAccount.setName or method myAccount.getName. These methods are called accessor methods, because they provide access to the Account class’s fields.
来源:https://stackoverflow.com/questions/11498287/accessor-methods-in-java