Getter and Setter

Why use getters and setters/accessors?

There are actually many good reasons to consider using accessors rather than directly exposing fields of a class - beyond just the argument of encapsulation and making future changes easier.

Here are the some of the reasons I am aware of:

  • Encapsulation of behavior associated with getting or setting the property - this allows additional functionality (like validation) to be added more easily later.
  • Hiding the internal representation of the property while exposing a property using an alternative representation.
  • Insulating your public interface from change - allowing the public interface to remain constant while the implementation changes without affecting existing consumers.
  • Controlling the lifetime and memory management (disposal) semantics of the property - particularly important in non-managed memory environments (like C++ or Objective-C).
  • Providing a debugging interception point for when a property changes at runtime - debugging when and where a property changed to a particular value can be quite difficult without this in some languages.
  • Improved interoperability with libraries that are designed to operate against property getter/setters - Mocking, Serialization, and WPF come to mind.
  • Allowing inheritors to change the semantics of how the property behaves and is exposed by overriding the getter/setter methods.
  • Allowing the getter/setter to be passed around as lambda expressions rather than values.
  • Getters and setters can allow different access levels - for example the get may be public, but the set could be protected.

What is the point of getters and setters?

Multiple reasons:

  • If you allow field access like

    shape.x = 90

then you cannot add any logic in future to validate the data.

say if x cannot be less than 100 you cannot do it, however if you had setters like

public void setShapeValue(int shapeValue){
if(shapeValue < 100){
//do something here like throw exception.
}
}
  • You cannot add something like copy on write logic (see CopyOnWriteArrayList)
  • Another reason is for accessing fields outside your class you will have to mark them public, protected or default, and thus you loose control. When data is very much internal to the class breaking Encapsulation and in general OOPS methodology.

Though for constants like

public final String SOMETHING = "SOMETHING";

you will allow field access as they cannot be changed, for instance variable you will place them with getters, setters.

  • Another scenario is when you want your Class to be immutable, if you allow field access then you are breaking the immutability of your class since values can be changed. But if you carefully design your class with getters and no setters you keep the immutability intact.

Though in such cases you have to be careful in getter method to ensure you don't give out reference of objects(in case your class have object as instances).

We can use the private variables in any package using getters and setters.

Is It Always Appropriate to Implement Getter and Setter Methods in Java Classes

In short, there's no hard-and-fast rule.

You include a getter for a field if you think there's a need for other classes to have access to it. It's entirely appropriate to not have a getter for a field that's entirely internal to your class' workings, and is not intended to be exposed. it's also entirely appropriate to have your getter return not the field itself, but some modified form of it, or an immutable copy of it (e.g., a copy of an internal List field).

You include a setter if you think there's a need for other classes to have free access to mutate the field. Omitting the setter essentially makes the field read-only. You can also opt to include a custom method to mutate your field, in lieu of the traditional setter (e.g., an add() method to add values to an internal List or Set, just to give an example). All approaches are entirely appropriate, depending on the circumstances.

EDIT: changed "property" to "field" in line with the established terminology

Lombok @Getter and @Setter annotations are not being recognised when getAnnoations() method is used

You cannot check for those annotations during runtime, as they are compile-time-only annotations (RetentionPolicy.SOURCE) which are discarded by the compiler and thus not present in the compiled class files.

There is no way to find out during runtime whether a setter/getter method was generated by lombok or written manually.

Can encapsulation be achieved in Java with getter and setter methods that are not public?

Encapsulation in Java is achieved by making a class's fields private. Weaker encapsulation is achieved by making them protected.

Getter and setter methods do not implement encapsulation. Rather, they provide a mechanism for certain kinds of interaction with encapsulated data. If the data were not encapsulated then getter and setter methods would not be required. As such, sure, you can provide protected or default-access getters and setters, and even private ones. Or none at all. It's all a question of what features you want your class to expose to whom.

When one makes getters and setters public it is because they provide features that are essential for use of the class, not because that level of access is a requirement for encapsulation.

Constructor and Getter- and Setter Methods

You actually can do that just make sure your getters and setters are public,an easy way to ensure your getters and setters are correct is to right click in your class->source->generate getters and setters then choose which attributes you want to be read and write,
However if your intention
with this line

    User admin = new User(username, fName, nName, password, 1);

is to create a new admin with these attributes

username = "admin";
fName = "name";
nName = "secondName";
password = "password";
group = 1;

maybe try instead:

either passing the values to the constructor directly without the variables

      User admin = new User ("admin","name","secondName",password,1);

or if you want for these to be the default values that an admin object is to have every time you create it then you can do this in the constructor:

     public Admin (){
super("admin","name","secondName",password,1);

then

    Admin admin = new admin();

then you can change the username like you want and if you want to check that it changed use

    System.out.println(admin.getUsername());

in both cases you don't really need to create the instance variables as they are inherited from user class.

How do getters and setters work in Python?

The reason to use a getter and setter, is if you want to do something more complex than just set and attribute with foo.bar. In your case, set_age has an

isinstance(new_age, int) & new_age>0 & new_age<120

check, which is not possible to do with a raw attribute. (Side-note: you should use and instead of &.)

Yes, someone can still do p1._age = -1, and then their code won't work, but why would they? It just makes their code not work.

Your get_name function is less useful than the age one. It basically makes name read-only, which might or might not be useful.

When creating setters and getters in Python, it is usual to use the @property decorator. This means the functions can be called as if they were attributes, so instead of p1.get_name() you can just do p1.name. Similarly p1.set_age(3) becomes p1.age = 3.

You probably want to use the age setter in __init__, because then the age of the Person is validated when it is created.

Here is a version that makes these changes (and a couple of other readability improvements).

class Person:
def __init__(self, name, age):
self._name = name
self.age = age

@property
def age(self):
return self._age

@age.setter
def age(self, new_age):
if isinstance(new_age, int) and 0 < new_age < 120:
self._age = new_age

@property
def name(self):
return self._name

def __str__(self):
return f"Person[{self.name}] is {self.age}"

p1 = Person("Sandeep", 49)

when to use getter and setter with property?

You should generally prefer to use "protected" variables (such as those starting with _) with properties (not separate functions that users need to call, that's just clunky), as it confers some advantages. This encapsulation is very handy as it:

  • lets you control the internal data completely, such as preventing people entering ages like -42 (which they will do if they can); and
  • lets you change the underlying implementation in any manner you want, without affecting clients.

For example on that last point, you may want to maintain a separate structure of all names and simply store references to those names in your Person class. This can allow you to store many more names, as the surname "Von Grimmelshausen" would be stored once (in the separate structure) and as much smaller indexes in all the Person objects that use it.

You can then totally change the naive getter from:

@property
def surname(self):
return self._surname

to:

@property
def surname(self):
return self._surname_db[self._surname_index]

without any changes to clients.

Getter and Setter methods

I hope that help you, that will give you at least a visibility and you can modify it as you want :

public class MyClass {

private String name;

private int age;

private String color;

private final List<String> colors = Arrays.asList("Black", "White", "Brown ", "Grey");

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getColor() {
return color;
}

public void setColor(String color) {
if (colors.contains(color)) {
this.color = color;
} else {
// if not valid do what you want
}
}

public int getAge() {
return age;
}

public void setAge(int age) {
if (age > 0 && age <= 100) {
this.age = age;
} else {
// if not valid do what you want
}
}

}


Related Topics



Leave a reply



Submit