In which scenarios do you use encapsulation? - java

I would like to know in what scenarios you use encapsulation. The purpose of this question is collaborative. So feel free to share your own experience when the subject is encapsulation.
Some scenarios:
Calculated property
public class Order {
private List<ListItem> listItems = new ArrayList<ListItem>();
public double getTotal() {
double total = 0;
for(ListItem listItem: listItems)
total += listItem.getQuantity() * listItem.getPropduct().getPrice();
return total;
}
}
Self-validating domain objects
public class Person {
private String name;
public void setName(String name) {
if(StringUtils.isBlank(name)) {
throw new NotEmptyException("name", name);
}
this.name = name;
}
}
Makes use of other kind of classes for some special behavior
public class Person {
private MutableInt id = new MutableInt();
/**
* Integer itself is immutable
*/
public Integer getId() {
retur id.intValue();
}
}
Conversion
public class Person {
public String enabled;
public boolean isEnabled() {
return "Y".equals(enabled);
}
}

Simply, I prefer to use strong encapsulation in all non-private APIs that I design/implement.
The only case where habitually don't use strong encapsulation is with private nested classes that are (and need to be) little more than ersatz struct declarations. My reasoning is that the private class is sufficiently encapsulated by being nested and private.
I am also prepared to relax encapsulation (a bit) if there are compelling performance reasons for doing this. This relaxation usually consists of leaking internal arrays / collections when the cost of copying them is prohibitive. And it always makes me feel uncomfortable doing this ...

I encapsulate when there is a scenario in which the user can screw it up. e.g., if I was writing a class that displayed text, I would not encapsulate the fact that I hold a string, because any string is valid for display.
Encapsulation exists for validation and interface change. If you have a parameter that needs no validation (and the interface is well-defined), there's no point in encapsulating it, especially if you use a language which doesn't come with any in-built tools for it, like Java (tools being, for example, C# properties).
Encapsulation is a tool like any other and should not be thrown all over everywhere just because you can.

Related

public modifier will break encapsulation property

We always say that, Encapsulation keeps data and functionality safe from the outside world.
So its a protective wrapper around the class and the code can be saved from unauthorized access by outer world.
But what if,
I declare one variable with public modifier will it break Encapsulation ?
Encapsulation in Java is a mechanism of wrapping the data (variables) and code acting on the data (methods) together as a single unit. In encapsulation, the variables of a class will be hidden from other classes, and can be accessed only through the methods of their current class. Therefore, it is also known as data hiding.
public class EncapTest {
private String name;
private String idNum;
private int age;
public int getAge() {
return age;
}
public String getName() {
return name;
}
public String getIdNum() {
return idNum;
}
public void setAge( int newAge) {
age = newAge;
}
public void setName(String newName) {
name = newName;
}
public void setIdNum( String newId) {
idNum = newId;
}
}
so that all your methods and variable should be private
In my idea modifiers absolutely supports Encapsulation. Maybe you just violate Information Hiding.
Encapsulation is not information hiding. Information hiding is a more fundamental technique than encapsulation. We should clarify between Encapsulation and Information Hiding. (see the reference)
Encapsulation is a technique for expressing the boundaries of
those modules.
Suppose that we have an attribute in our class and we need to set some values from external the class. We can not define it as public. We can not define it as protected too (see this question), the only way to define this types of conditions is defining some methods (or some modifiers in very simple interface). In this case we Encapsulate it.
So what is the difference between a public attribute and a private attribute with modifiers?
In a very big projects, we can add some other conditions to modifiers without any changes to other parts of project (the OCP of SOLID).
Finally: In some cases we need to set some values from outside the class to attributes. So sometimes we need to use modifiers and it is the encapsulation way to access the fields. We can not define the fields as public or protected in OOP.
First of all, let's see what encapsulation really is.
Encapsulation is one of the four OOP concepts.
In encapsulation, the variables of a class will be hidden from other classes, and can be accessed only through the methods of their current class. Therefore, it is also known as data hiding.
So making a class variable public it's not encapsulation anymore.
Let's see some real usages of encapsulation:
By encapsulating, you force yourself and other developers to access that variable through their getters and setters. Let's be honest, it's the same thing as if the field was public, right?
But what if you add some logic to the setters?
public class User {
private String username;
private String password;
// username getter and setter not displayed in this example.
public void setPassword(String password) {
this.password = someCoolHashingMethod(password);
}
public String getPassword() {
return this.password;
}
}
Do you see what's happening there? You force the password to be stored as a hash instead of clear. (There are many ways to protect a password but we'll stick to this dummy example for now).
Another real use for encapsulation is that you can change the name of the variable without changing the code everywhere in your application.
So you if you change it's name and it's not encapsulated, you will have to go everywhere you used it, modified it, to change there aswell. So a project level refactorization is needed. But if it's encapsulated, you used getters and setters everywhere! That means you just need to change it there only. Example:
public class User {
private String username;
private String pass; // <---- notice the new name
// username getter and setter not displayed in this example.
public void setPassword(String password) {
this.pass = someCoolHashingMethod(password); // <---- notice the new name
}
public String getPassword() {
return this.pass; // <---- notice the new name
}
}
Hope this answered a little bit more than your question really was.

Java encapsulation concept not very clear

I have a bit of confusion with encapsulation concept. I have gone through quite a few answers on the same , but still confused. As far as I understand, encapsulation is to make instance variables as private so that outside cannot access this directly. Public getter and setter methods would be provided to access the private variables.
Suppose we have a class like below :
class Address
{
int doorNumber;
public int getDoorNumber()
{
//some code
}
public void setDoorNumber(int doorNumber)
{
//some code
}
}
We have another class from which we are trying to access the variable of Address class.
class TestAddress
{
public static void main()
{
Address add=new Address();
add.doorNumber=10; //cannot be done
add.setDoorNumber(10);
}
}
Though we are not accessing the variable directly , we are still modifying doorNumber using setter method to set the value of it to 10 . Basically the outside world can still access the private field and modify it in the way it wants. I do not understand what is the point of having encapsulation then . Can you please provide me some examples to understand encapsulation . Also scenarios where encapsulation was not used and problems which can occur because of that.
Look at the following counter-example:
class Address
{
int floor, door;
public int getDoorNumber()
{
return floor*100+door;
}
public void setDoorNumber(int doorNumber)
{
int newFloor=doorNumber/100;
if(newFloor<0 || newFloor>6)
throw new IllegalArgumentException("no such door "+doorNumber);
floor=newFloor;
door=doorNumber-newFloor*100;
}
}
The code calling setDoorNumber(10) still works without needing any change. The independence of the property “doorNumber” from the object’s internal representation, plus the possibility to validate the input value, are the key point of encapsulation. You can’t do that with a field like public int doorNumber;
Besides that, there are developers considering a method like setDoorNumber(int) being contradicting encapsulation, or at least, be a weak form of encapsulation. A stronger encapsulation model would work without such a public setter method but providing high-level operations only. Such an operation, like booking a room in a hotel would perform much more related operations, involving other objects, and consistency checks before internally assigning a room number to an address…
Using getters and setters has some benefits over making fields public :
You can redesign the internals of your class by replacing int doorNumber; with one or more fields of possibly different type. In such a case you can keep the getter and setter and that means other classes wouldn't have to be modified. If you had preferred private fields, any change in this class would enforce changes in any other class that uses it.
You can add validation and or reformatting logic inside a setter or getter, without changing the type of the field. Otherwise, if you used public fields, this logic would have to be repeated in any other class that accesses this field.
You can read more about it at Effective Java item 14
Consider this example:
public class Address {
private int doorNumber;
public int getDoorNumber() {
return doorNumber;
}
public void setDoorNumber(int doorNumber) {
if (doorNumber <= 0) {
throw new IllegalArgumentException("door number must be > 0");
}
this.doorNumber = doorNumber;
}
}
If the doorNumber field was declared as public, some code could violate the constraint that the door numbers in addresses should be positive numbers.
Consider this example:
public class Address {
private String doorNumber;
public int getDoorNumber() {
return Integer.parseInt(doorNumber);
}
public String getDoorNumber2() {
return doorNumber;
}
public void setDoorNumber(int doorNumber) {
this.doorNumber = doorNumber + "";
}
public void setDoorNumber(String doorNumber) {
this.doorNumber = doorNumber;
}
}
Note that we evolving our API so that we can represent the address "221B Baker St, London", but still allowing our old "house numbers are integers" API to be used ... (sort of).
But if doorNumber had been public, then we would have been forced to change every place in the codebase where Address.doorNumber had been used.

Java how do I use a set Method? [duplicate]

How can I use the set and get methods, and why should I use them? Are they really helpful? And also can you give me examples of set and get methods?
Set and Get methods are a pattern of data encapsulation. Instead of accessing class member variables directly, you define get methods to access these variables, and set methods to modify them. By encapsulating them in this manner, you have control over the public interface, should you need to change the inner workings of the class in the future.
For example, for a member variable:
Integer x;
You might have methods:
Integer getX(){ return x; }
void setX(Integer x){ this.x = x; }
chiccodoro also mentioned an important point. If you only want to allow read access to the field for any foreign classes, you can do that by only providing a public get method and keeping the set private or not providing a set at all.
I want to add to other answers that setters can be used to prevent putting the object in an invalid state.
For instance let's suppose that I've to set a TaxId, modelled as a String. The first version of the setter can be as follows:
private String taxId;
public void setTaxId(String taxId) {
this.taxId = taxId;
}
However we'd better prevent the use to set the object with an invalid taxId, so we can introduce a check:
private String taxId;
public void setTaxId(String taxId) throws IllegalArgumentException {
if (isTaxIdValid(taxId)) {
throw new IllegalArgumentException("Tax Id '" + taxId + "' is invalid");
}
this.taxId = taxId;
}
The next step, to improve the modularity of the program, is to make the TaxId itself as an Object, able to check itself.
private final TaxId taxId = new TaxId()
public void setTaxId(String taxIdString) throws IllegalArgumentException {
taxId.set(taxIdString); //will throw exception if not valid
}
Similarly for the getter, what if we don't have a value yet? Maybe we want to have a different path, we could say:
public String getTaxId() throws IllegalStateException {
return taxId.get(); //will throw exception if not set
}
I think you want something like this:
public class Person {
private int age;
//public method to get the age variable
public int getAge(){
return this.age
}
//public method to set the age variable
public void setAge(int age){
this.age = age;
}
}
You're simply calling such a method on an object instance. Such methods are useful especially if setting something is supposed to have side effects. E.g. if you want to react to certain events like:
public void setAge(int age){
this.age = age;
double averageCigarettesPerYear = this.smokedCigarettes * 1.0 / age;
if(averageCigarettesPerYear >= 7300.0) {
this.eventBus.fire(new PersonSmokesTooMuchEvent(this));
}
}
Of course this can be dangerous if somebody forgets to call setAge(int) where he should and sets age directly using this.age.
Setters and getters are used to replace directly accessing member variables from external classes. if you use a setter and getter in accessing a property, you can include initialization, error checking, complex transformations, etc. Some examples:
private String x;
public void setX(String newX) {
if (newX == null) {
x = "";
} else {
x = newX;
}
}
public String getX() {
if (x == null) {
return "";
} else {
return x;
}
}
Having accessor methods is preferred to accessing fields directly, because it controls how fields are accessed (may impose data checking etc) and fits with interfaces (interfaces can not requires fields to be present, only methods).
Some benefits of using getters and setters (known as encapsulation or data-hiding):
(originally answered here)
1. The fields of a class can be made read-only (by only providing the getter) or write-only (by only providing the setter). This gives the class a total control of who gets to access/modify its fields.
Example:
class EncapsulationExample {
private int readOnly = -1; // this value can only be read, not altered
private int writeOnly = 0; // this value can only be changed, not viewed
public int getReadOnly() {
return readOnly;
}
public int setWriteOnly(int w) {
writeOnly = w;
}
}
2. The users of a class do not need to know how the class actually stores the data. This means data is separated and exists independently from the users thus allowing the code to be more easily modified and maintained. This allows the maintainers to make frequent changes like bug fixes, design and performance enhancements, all while not impacting users.
Furthermore, encapsulated resources are uniformly accessible to each user and have identical behavior independent of the user since this behavior is internally defined in the class.
Example (getting a value):
class EncapsulationExample {
private int value;
public int getValue() {
return value; // return the value
}
}
Now what if I wanted to return twice the value instead? I can just alter my getter and all the code that is using my example doesn't need to change and will get twice the value:
class EncapsulationExample {
private int value;
public int getValue() {
return value*2; // return twice the value
}
}
3. Makes the code cleaner, more readable and easier to comprehend.
Here is an example:
No encapsulation:
class Box {
int widthS; // width of the side
int widthT; // width of the top
// other stuff
}
// ...
Box b = new Box();
int w1 = b.widthS; // Hm... what is widthS again?
int w2 = b.widthT; // Don't mistake the names. I should make sure I use the proper variable here!
With encapsulation:
class Box {
private int widthS; // width of the side
private int widthT; // width of the top
public int getSideWidth() {
return widthS;
}
public int getTopWIdth() {
return widthT;
}
// other stuff
}
// ...
Box b = new Box();
int w1 = b.getSideWidth(); // Ok, this one gives me the width of the side
int w2 = b.getTopWidth(); // and this one gives me the width of the top. No confusion, whew!
Look how much more control you have on which information you are getting and how much clearer this is in the second example. Mind you, this example is trivial and in real-life the classes you would be dealing with a lot of resources being accessed by many different components. Thus, encapsulating the resources makes it clearer which ones we are accessing and in what way (getting or setting).
Here is good SO thread on this topic.
Here is good read on data encapsulation.
The above answers summarize the role of getters and setters better than I could, however I did want to add that your code should ideally be structured to reduce the use of pure getters and setters, i.e. those without complex constructions, validation, and so forth, as they break encapsulation. This doesn't mean you can't ever use them (stivlo's answer shows an example of a good use of getters and setters), just try to minimize how often you use them.
The problem is that getters and setters can act as a workaround for direct access of private data. Private data is called private because it's not meant to be shared with other objects; it's meant as a representation of the object's state. Allowing other objects to access an object's private fields defeats the entire purpose of setting it private in the first place. Moreover, you introduce coupling for every getter or setter you write. Consider this, for example:
private String foo;
public void setFoo(String bar) {
this.foo = bar;
}
What happens if, somewhere down the road, you decide you don't need foo anymore, or you want to make it an integer? Every object that uses the setFoo method now needs to be changed along with foo.
just because the OOP rule: Data Hiding and Encapsulation. It is a very bad practice to declare a object's as public and change it on the fly in most situations. Also there are many other reasons , but the root is Encapsulation in OOP. and "buy a book or go read on Object Oriented Programming ", you will understand everything on this after you read any book on OOP.
The benefits of get() set() methods are as follows ..
You can serialize you object easily.
You can create a persistent object from the containing class.
You can convert the properties to JSON easily.
In the DAO layer (Frameworks like Hibernate) you can directly save the object to DB.
Easy understanding of object oriented concept.
Needs in all design pattern except possibly in single tone pattern.
Security for properties protecting direct access.
Polymorphism, Encapsulation can be easily understood and implemented by this type of class.
Example:
private String personName;
private int personId;
public void setPersonName(String name) throws Exception{
if(!(name.equals("")||name=="")){
this.personName = name;
}
}
public String getPersonName(){
return this.personName;
}
public void setPersonId(int id) throws Exception{
this.personId = id;
}
public int getPersonId(){
return this.personId;
}
Above answers all assume that the object in question is an object with behaviour.
An advanced strategy in OOP is to separate data objects (that do zip, only have fields) and behaviour objects.
With data objects, it is perfectly fine to omit getters and instead have public fields. They usually don't have setters, since they most commonly are immutable - their fields are set via the constructors, and never again.
Have a look at Bob Martin's Clean Code or Pryce and Freeman's Growing OO Software... for details.
public class Person{
private int age;
public int getAge(){
return age;
}
public void setAge(int age){
this.age = age;
}
}
i think this is you want..
and this also called pojo
this is the code for set method
public void setAge(int age){
this.age = age;
}
It looks like you trying to do something similar to C# if you want setAge create method setAge(int age){
this.age = age;}
I don't see a simple answer to the second question (why) here. So here goes.
Let's say you have a public field that gets used very often in your code. Whenever you decide you need to do something extra before you give or set this field you have a problem. You have to create a special getter and setter for this field and change your complete code from using the field directly to using the getter and setters.
Now imagine you are developing a library widely used by many people. When you need to make a change like the above and set direct access of the field to private the code of all the people using this field will break.
Using getters and setters is about future planning of the code, it makes it more flexible. Of course you can use public fields, especially for simple classes that just hold some data. But it's always a good idea to just make the field privately and code a get and set method for it.
This answer is merged from another question.
Your getAge() method is called instance method in Java.
To invoke an instance method, you should have a object of the Class in which this method is defined.
For Example, If this method in a Class called Person, then
Create a Person object using new operator
Person p = new Person();
To get the age of a Person object, use this method
p.getAge()
Although still a second year undergraduate student I will say my opinion. I believe that Java and private variables within your class are "RULES". Therefore because the variables in your class are private I think you use getters and setters to be able to define these variables outside the class.

How to extend immutable types in Java

I have started playing around with immutable value objects in Java while working on a game project, following the "public final fields" approach:
public class Team {
public final String name, flag;
public Team(String name, String flag) {
this.name = name;
this.flag = flag;
}
}
This works pretty well for me so far, but I need different sets of extra information about the team in different circumstances. For example, a team has a set color during a match. The question is, what is the best way to deal with these sets of extended information? I know this is a fairly general question, but I want to keep using immutable objects and that might influence the solution.
Here are the options I have come up with. Most of them are probably "good enough", but I'd like to learn some arguments for and against them for future reference.
Option 1: Everything in one class
public class Team {
public final String name, flag, colorName;
public final int colorRgb;
public Team(String name, String flag, String colorName, int colorRgb) {
this.name = name;
this.flag = flag;
this.colorName = colorName;
this.colorRgb = colorRgb;
}
}
This takes only one class for all uses, but there is no type-based indication of what extra data is expected/provided.
Option 2: Subclassing
public class TeamWithColor extends Team {
public final String colorName;
public final int colorRgb;
public Team(String name, String flag, String colorName, int colorRgb) {
super(name, flag);
this.colorName = colorName;
this.colorRgb = colorRgb;
}
}
This might make a content-based equals() implementation impossible.
Option 3: Composition
public class TeamWithColor {
public final Team team;
public final String colorName;
public final int colorRgb;
public Team(Team team, String colorName, int colorRgb) {
this.team = team;
this.colorName = colorName;
this.colorRgb = colorRgb;
}
}
Less copying / boilerplate code if the team data and extra data often change independently.
Option 4: Pair/Tuple (using an immutable Pair class)
public class TeamColor {
public final String colorName;
public final int colorRgb;
public Team(String colorName, int colorRgb) {
this.colorName = colorName;
this.colorRgb = colorRgb;
}
}
Pair<Team, TeamColor> teamWithColor = Pair.create(team, teamColor);
... or with a custom class that ties Team and TeamColor together.
I tend toward option 3 or 4, but I'm interested in your opinions, arguments and gut feelings :)
As you said. The team can appear in different circumstances.
These circumstances are the context giving the team the additional attributes.
Therefore I suggest using composition for each different context that add's data.
public class TeamWithColor {
public final Team team;
public final TeamColor teamColor;
public TeamWithColor(Team team, TeamColor teamColor) {
this.team = team;
this.teamColor = teamColor;
}
}
Maybe you'll have :
public class TeamDuringOlimpics{
public final Team team;
public final TeamColor teamColor;
public final TeamFlag teamFlag;
public TeamDuringOlimpics(Team team, TeamColor teamColor, TeamFlag teamFlagTeamFlag teamFlag) {
this.team = team;
this.teamColor = teamColor;
this.teamFlag = teamFlag;
}
}
Composition sounds like a good option for adding contextual data that is required to be mutable.
In Java immutable classes are usually marked final and cannot be extended. See String as an example. That rules out option number 2.
Be weary of using Pairs. There are many good reasons the Pair type has not been added to Java. In this case your data is better modeled by creating a new data type (i.e. thru composition).
Recommended best practices for creating immutable classes: http://www.javapractices.com/topic/TopicAction.do?Id=29
If an immutable class is inheritable, or if contains aspects whose types could be mutable, then it will have no security against mischief. A "immutable" interface will likewise have no security. Likewise also if an object has any members of extensible types, and object is regarded as containing any of the information in the objects referred to by those members. It is up to you to decide whether or not that is a problem. Immutable interfaces and extensible mutable classes may be much more versatile than deeply-sealed ones; if a class isn't going to be deeply sealed, there's little security advantage to making it partially so.
Note that it is possible for a deeply-immutable object to have a field which is of a mutable type, if the semantics of the field specify that it identifies, rather than contains, the object in question. For example, it may be useful to have have a "snapshot" object which contains references to some mutable objects and, for each object, an immutable copy of its current state; the "snapshot" object would then expose a method of restoring each object to the state it had when the snapshot was generated. The snapshot object would be "deeply immutable" despite its reference to a mutable object, since the snapshot's references to the mutable objects exist purely to identify them, and the identities of those objects wouldn't change even if their state does.
One pattern that I like in .net, which should also work in Java, is to have interfaces like IReadableFoo and IImmutableFoo; the latter would inherit the former but not add any new members. The interface IReadableFoo should contain, in addition to members to read its properties, a member AsImmutable() which would return an IImmutableFoo. This approach allows code to use mutable types when convenient, while minimizing redundant defensive copying (code which wants to persist something must call AsImmutable() on it; if the object in question is mutable, that action will create an immutable copy, but if the object is already immutable, no new copy will be required).
You could consider keeping this piece of information outside the Team object. For instance, you could have a Map or Map
This way, you could enrich your objects with many additional values without introducing new classes or modifying existing classes. Moreover, it would keep the immutable property of the other objects.
I recommend the Decorator pattern.
public class TeamWithColor extends Team {
public final Team team;
public final String colorName;
public final int colorRgb;
public Team(Team team, String colorName, int colorRgb) {
this.team = team;
this.colorName = colorName;
this.colorRgb = colorRgb;
}
}
http://en.wikipedia.org/wiki/Decorator_pattern
I usually try to avoid putting everything in one class (option 1) this leaves us 4 options
in case I needed the class to be thread-safe I favor using a volatile/AtomicReference of an Immutable tuple (option 4) instead of using locks and other blocking syncs (let's call it: option 5)
if thread-safety isn't a concern then I would pick Composition (option 3) over In inheritance (option 2) unless an IS-A relation naturally exist
a Colored Team IS a Team after all, so I would be nice to exploit this relation. if I were you I would code it like this:
public final class ColoredTeam extends AbstractTeam implements Team {
// the rest comes along intuitively
}
since "AbstractTeam" is abstract, content-based equals() implementation is perfectly fine as long "ColoredTeam" itself has no subclasses, I made ColoredTeam final to achieve this but I could have made the contractor private, throws an exception, etc.

Set and Get Methods in java?

How can I use the set and get methods, and why should I use them? Are they really helpful? And also can you give me examples of set and get methods?
Set and Get methods are a pattern of data encapsulation. Instead of accessing class member variables directly, you define get methods to access these variables, and set methods to modify them. By encapsulating them in this manner, you have control over the public interface, should you need to change the inner workings of the class in the future.
For example, for a member variable:
Integer x;
You might have methods:
Integer getX(){ return x; }
void setX(Integer x){ this.x = x; }
chiccodoro also mentioned an important point. If you only want to allow read access to the field for any foreign classes, you can do that by only providing a public get method and keeping the set private or not providing a set at all.
I want to add to other answers that setters can be used to prevent putting the object in an invalid state.
For instance let's suppose that I've to set a TaxId, modelled as a String. The first version of the setter can be as follows:
private String taxId;
public void setTaxId(String taxId) {
this.taxId = taxId;
}
However we'd better prevent the use to set the object with an invalid taxId, so we can introduce a check:
private String taxId;
public void setTaxId(String taxId) throws IllegalArgumentException {
if (isTaxIdValid(taxId)) {
throw new IllegalArgumentException("Tax Id '" + taxId + "' is invalid");
}
this.taxId = taxId;
}
The next step, to improve the modularity of the program, is to make the TaxId itself as an Object, able to check itself.
private final TaxId taxId = new TaxId()
public void setTaxId(String taxIdString) throws IllegalArgumentException {
taxId.set(taxIdString); //will throw exception if not valid
}
Similarly for the getter, what if we don't have a value yet? Maybe we want to have a different path, we could say:
public String getTaxId() throws IllegalStateException {
return taxId.get(); //will throw exception if not set
}
I think you want something like this:
public class Person {
private int age;
//public method to get the age variable
public int getAge(){
return this.age
}
//public method to set the age variable
public void setAge(int age){
this.age = age;
}
}
You're simply calling such a method on an object instance. Such methods are useful especially if setting something is supposed to have side effects. E.g. if you want to react to certain events like:
public void setAge(int age){
this.age = age;
double averageCigarettesPerYear = this.smokedCigarettes * 1.0 / age;
if(averageCigarettesPerYear >= 7300.0) {
this.eventBus.fire(new PersonSmokesTooMuchEvent(this));
}
}
Of course this can be dangerous if somebody forgets to call setAge(int) where he should and sets age directly using this.age.
Setters and getters are used to replace directly accessing member variables from external classes. if you use a setter and getter in accessing a property, you can include initialization, error checking, complex transformations, etc. Some examples:
private String x;
public void setX(String newX) {
if (newX == null) {
x = "";
} else {
x = newX;
}
}
public String getX() {
if (x == null) {
return "";
} else {
return x;
}
}
Having accessor methods is preferred to accessing fields directly, because it controls how fields are accessed (may impose data checking etc) and fits with interfaces (interfaces can not requires fields to be present, only methods).
Some benefits of using getters and setters (known as encapsulation or data-hiding):
(originally answered here)
1. The fields of a class can be made read-only (by only providing the getter) or write-only (by only providing the setter). This gives the class a total control of who gets to access/modify its fields.
Example:
class EncapsulationExample {
private int readOnly = -1; // this value can only be read, not altered
private int writeOnly = 0; // this value can only be changed, not viewed
public int getReadOnly() {
return readOnly;
}
public int setWriteOnly(int w) {
writeOnly = w;
}
}
2. The users of a class do not need to know how the class actually stores the data. This means data is separated and exists independently from the users thus allowing the code to be more easily modified and maintained. This allows the maintainers to make frequent changes like bug fixes, design and performance enhancements, all while not impacting users.
Furthermore, encapsulated resources are uniformly accessible to each user and have identical behavior independent of the user since this behavior is internally defined in the class.
Example (getting a value):
class EncapsulationExample {
private int value;
public int getValue() {
return value; // return the value
}
}
Now what if I wanted to return twice the value instead? I can just alter my getter and all the code that is using my example doesn't need to change and will get twice the value:
class EncapsulationExample {
private int value;
public int getValue() {
return value*2; // return twice the value
}
}
3. Makes the code cleaner, more readable and easier to comprehend.
Here is an example:
No encapsulation:
class Box {
int widthS; // width of the side
int widthT; // width of the top
// other stuff
}
// ...
Box b = new Box();
int w1 = b.widthS; // Hm... what is widthS again?
int w2 = b.widthT; // Don't mistake the names. I should make sure I use the proper variable here!
With encapsulation:
class Box {
private int widthS; // width of the side
private int widthT; // width of the top
public int getSideWidth() {
return widthS;
}
public int getTopWIdth() {
return widthT;
}
// other stuff
}
// ...
Box b = new Box();
int w1 = b.getSideWidth(); // Ok, this one gives me the width of the side
int w2 = b.getTopWidth(); // and this one gives me the width of the top. No confusion, whew!
Look how much more control you have on which information you are getting and how much clearer this is in the second example. Mind you, this example is trivial and in real-life the classes you would be dealing with a lot of resources being accessed by many different components. Thus, encapsulating the resources makes it clearer which ones we are accessing and in what way (getting or setting).
Here is good SO thread on this topic.
Here is good read on data encapsulation.
The above answers summarize the role of getters and setters better than I could, however I did want to add that your code should ideally be structured to reduce the use of pure getters and setters, i.e. those without complex constructions, validation, and so forth, as they break encapsulation. This doesn't mean you can't ever use them (stivlo's answer shows an example of a good use of getters and setters), just try to minimize how often you use them.
The problem is that getters and setters can act as a workaround for direct access of private data. Private data is called private because it's not meant to be shared with other objects; it's meant as a representation of the object's state. Allowing other objects to access an object's private fields defeats the entire purpose of setting it private in the first place. Moreover, you introduce coupling for every getter or setter you write. Consider this, for example:
private String foo;
public void setFoo(String bar) {
this.foo = bar;
}
What happens if, somewhere down the road, you decide you don't need foo anymore, or you want to make it an integer? Every object that uses the setFoo method now needs to be changed along with foo.
just because the OOP rule: Data Hiding and Encapsulation. It is a very bad practice to declare a object's as public and change it on the fly in most situations. Also there are many other reasons , but the root is Encapsulation in OOP. and "buy a book or go read on Object Oriented Programming ", you will understand everything on this after you read any book on OOP.
The benefits of get() set() methods are as follows ..
You can serialize you object easily.
You can create a persistent object from the containing class.
You can convert the properties to JSON easily.
In the DAO layer (Frameworks like Hibernate) you can directly save the object to DB.
Easy understanding of object oriented concept.
Needs in all design pattern except possibly in single tone pattern.
Security for properties protecting direct access.
Polymorphism, Encapsulation can be easily understood and implemented by this type of class.
Example:
private String personName;
private int personId;
public void setPersonName(String name) throws Exception{
if(!(name.equals("")||name=="")){
this.personName = name;
}
}
public String getPersonName(){
return this.personName;
}
public void setPersonId(int id) throws Exception{
this.personId = id;
}
public int getPersonId(){
return this.personId;
}
Above answers all assume that the object in question is an object with behaviour.
An advanced strategy in OOP is to separate data objects (that do zip, only have fields) and behaviour objects.
With data objects, it is perfectly fine to omit getters and instead have public fields. They usually don't have setters, since they most commonly are immutable - their fields are set via the constructors, and never again.
Have a look at Bob Martin's Clean Code or Pryce and Freeman's Growing OO Software... for details.
public class Person{
private int age;
public int getAge(){
return age;
}
public void setAge(int age){
this.age = age;
}
}
i think this is you want..
and this also called pojo
this is the code for set method
public void setAge(int age){
this.age = age;
}
It looks like you trying to do something similar to C# if you want setAge create method setAge(int age){
this.age = age;}
I don't see a simple answer to the second question (why) here. So here goes.
Let's say you have a public field that gets used very often in your code. Whenever you decide you need to do something extra before you give or set this field you have a problem. You have to create a special getter and setter for this field and change your complete code from using the field directly to using the getter and setters.
Now imagine you are developing a library widely used by many people. When you need to make a change like the above and set direct access of the field to private the code of all the people using this field will break.
Using getters and setters is about future planning of the code, it makes it more flexible. Of course you can use public fields, especially for simple classes that just hold some data. But it's always a good idea to just make the field privately and code a get and set method for it.
This answer is merged from another question.
Your getAge() method is called instance method in Java.
To invoke an instance method, you should have a object of the Class in which this method is defined.
For Example, If this method in a Class called Person, then
Create a Person object using new operator
Person p = new Person();
To get the age of a Person object, use this method
p.getAge()
Although still a second year undergraduate student I will say my opinion. I believe that Java and private variables within your class are "RULES". Therefore because the variables in your class are private I think you use getters and setters to be able to define these variables outside the class.

Categories