Initializing ivars in Java - java

Is there a difference or preferred preference between declaring and setting the default ivars like so:
public class Foo
{
private int yes = 0;
private String name = "";
//...
//constructors, setters, getters, etc.
}
public class Foo
{
private int yes;
private String name;
public Foo()
{
yes = 0;
name = "";
}
//...
//setters, getters, etc.
}
Also, in constructors and other methods in Foo should I be setting and getting the ivars with the accessor and mutator methods or with simply assigning them directly?

primitive types (int in your case) are initialized by default values automatically, so there no reason to explicitly set it to 0;
What about Strings and other objects: it's completely depends on your preferences. I prefer not to initialize it in constructor. But keep in mind that in case of initilizing fields in constructor you can handle exceptions if field initializing throws some exception

Same thing. Accessor and mutators methods will be needed for external classes.

It doesn't matter and it's basically personal preference. Java compiler copies the initialization from a class to every constructor (no extra calls, it's really a direct copy in the bytecode).
Personally, I prefer to put the data-independent initialization to the class while I put the data that might depend on the constructor parameters to the constructor itself.

Related

Returned object changes private reference variable values

Say I have a class with a reference type variable in it. I don't want the stored values of the object that this variable stores to be able to change, but I want to be able to get the object itself/access its values. This calls for making it private and creating a getter, but no setter. Doing this however only limits my ability to change the object that the variable points to, but it doesn't prevent me from changing the values of the object itself.
private void program(){
Test test = new Test(3);
out.println(test.getA().a); // initial value, prints 3
test.getA().a = 4; // changes referenced value through getter, even though the object is private, and has no setter
out.println(test.getA().a); // changed value, prints 4
}
class Test{
private A a;
public Test(int a){
this.a = new A(a);
}
public A getA(){
return a;
}
}
class A{
public int a;
public A(int a){
this.a = a;
}
}
In the code above I can use the getter to access the object's values, even though I made the variable private to try to prevent this from happening. The only way that I see around this is to create a new A object that I return every time I call the getter method, but to me this seems inefficient as it takes up unnecessary space in memory.
Is there a better way of reading the object while still preventing change or am I missing something?
Thanks in advance.
This is a common problem and there are 2 main solutions:
The way you described with copy-constructor or clone() method in getter
You can make your A class immutable - just make all fields final and initialize it once through constructor or nested builder
Also i advise not to make value-type fields public AT ALL
Usefull links:
https://www.baeldung.com/java-immutable-object
https://www.journaldev.com/129/how-to-create-immutable-class-in-java
https://web.mit.edu/6.005/www/fa15/classes/09-immutability/

Strategy for Immutable Classes - Is this a contradiction?

The strategy for defining an immutable class contains 2 points:
Mark the field as private and final
Don't provide setters
My point of confusion is: when I have marked the field as private final, what extra safety does omitting setters will give?
Since the field is private, it cannot be accessed outside the class without a class method. But since it is also final, it cannot be modified after it has been initialized.
Suppose, in the following class, if I do not initialize my field at the 2 places highlighted, then compiler will give me error that final blank field has not been initialized which means marking the filed as final, won't let me construct an object without initializing the final field which means only 1 value of such a field will exist after object creation
class MyImmutable {
private final int field1; // either initialze here
MyImmutable() {
this.field1 = ... ; // or here
}
}
Nope. The article is just being explicit about the properties of an immutable type.
They quoted the word "setter" and followed it with a precise defintion. The exact quote states:
Don't provide "setter" methods — methods that modify fields or objects referred to by fields
private final doesn't always ensure immutability. In your example, private final is sufficient because field1 is a primitive type.
Take a closer look at the quote:
methods that modify fields or objects referred to by fields
If MyImmutable was composed of a mutable type, setters could delegate calls to them, resulting in MyImmutable being mutated, regardless of whether fields within MyImmutable were marked private final or not.
Here's an example of using private final, but the type consists of a mutable type, which a setter delegates calls to:
#Immutable
class Person {
private final Identity identity; // Identity is a mutable type
public void changeNameTo(String name) {
identity.changeNameTo(name); // private final can't prevent this
}
}
#Mutable
class Identity {
private String name;
public void changeNameTo(String name) {
this.name = name;
}
}
Which is a common tactic when decomposing existing code.

Immutable Matrix ADT [duplicate]

How to create immutable objects in Java?
Which objects should be called immutable?
If I have class with all static members is it immutable?
Below are the hard requirements of an immutable object.
Make the class final
make all members final, set them
explicitly, in a static block, or in the constructor
Make all members private
No Methods that modify state
Be extremely careful to limit access to mutable members(remember the field may be final but the object can still be mutable. ie private final Date imStillMutable). You should make defensive copies in these cases.
The reasoning behind making the class final is very subtle and often overlooked. If its not final people can freely extend your class, override public or protected behavior, add mutable properties, then supply their subclass as a substitute. By declaring the class final you can ensure this won't happen.
To see the problem in action consider the example below:
public class MyApp{
/**
* #param args
*/
public static void main(String[] args){
System.out.println("Hello World!");
OhNoMutable mutable = new OhNoMutable(1, 2);
ImSoImmutable immutable = mutable;
/*
* Ahhhh Prints out 3 just like I always wanted
* and I can rely on this super immutable class
* never changing. So its thread safe and perfect
*/
System.out.println(immutable.add());
/* Some sneak programmer changes a mutable field on the subclass */
mutable.field3=4;
/*
* Ahhh let me just print my immutable
* reference again because I can trust it
* so much.
*
*/
System.out.println(immutable.add());
/* Why is this buggy piece of crap printing 7 and not 3
It couldn't have changed its IMMUTABLE!!!!
*/
}
}
/* This class adheres to all the principles of
* good immutable classes. All the members are private final
* the add() method doesn't modify any state. This class is
* just a thing of beauty. Its only missing one thing
* I didn't declare the class final. Let the chaos ensue
*/
public class ImSoImmutable{
private final int field1;
private final int field2;
public ImSoImmutable(int field1, int field2){
this.field1 = field1;
this.field2 = field2;
}
public int add(){
return field1+field2;
}
}
/*
This class is the problem. The problem is the
overridden method add(). Because it uses a mutable
member it means that I can't guarantee that all instances
of ImSoImmutable are actually immutable.
*/
public class OhNoMutable extends ImSoImmutable{
public int field3 = 0;
public OhNoMutable(int field1, int field2){
super(field1, field2);
}
public int add(){
return super.add()+field3;
}
}
In practice it is very common to encounter the above problem in Dependency Injection environments. You are not explicitly instantiating things and the super class reference you are given may actually be a subclass.
The take away is that to make hard guarantees about immutability you have to mark the class as final. This is covered in depth in Joshua Bloch's Effective Java and referenced explicitly in the specification for the Java memory model.
Just don't add public mutator (setter) methods to the class.
Classes are not immutable, objects are.
Immutable means: my public visible state cannot change after initialization.
Fields do not have to be declared final, though it can help tremendously to ensure thread safety
If you class has only static members, then objects of this class are immutable, because you cannot change the state of that object ( you probably cannot create it either :) )
To make a class immutable in Java , you can keep note of the following points :
1. Do not provide setter methods to modify values of any of the instance variables of the class.
2. Declare the class as 'final' . This would prevent any other class from extending it and hence from overriding any method from it which could modify instance variable values.
3. Declare the instance variables as private and final.
4. You can also declare the constructor of the class as private and add a factory method to create an instance of the class when required.
These points should help!!
From oracle site, how to create immutable objects in Java.
Don't provide "setter" methods — methods that modify fields or objects referred to by fields.
Make all fields final and private.
Don't allow subclasses to override methods. The simplest way to do this is to declare the class as final. A more sophisticated approach is to make the constructor private and construct instances in factory methods.
If the instance fields include references to mutable objects, don't allow those objects to be changed:
I. Don't provide methods that modify the mutable objects.
II. Don't share references to the mutable objects. Never store references to external, mutable objects passed to the constructor; if necessary, create copies, and store references to the copies. Similarly, create copies of your internal mutable objects when necessary to avoid returning the originals in your methods.
An immutable object is an object that will not change its internal state after creation. They are very useful in multithreaded applications because they can be shared between threads without synchronization.
To create an immutable object you need to follow some simple rules:
1. Don't add any setter method
If you are building an immutable object its internal state will never change. Task of a setter method is to change the internal value of a field, so you can't add it.
2. Declare all fields final and private
A private field is not visible from outside the class so no manual changes can't be applied to it.
Declaring a field final will guarantee that if it references a primitive value the value will never change if it references an object the reference can't be changed. This is not enough to ensure that an object with only private final fields is not mutable.
3. If a field is a mutable object create defensive copies of it for
getter methods
We have seen before that defining a field final and private is not enough because it is possible to change its internal state. To solve this problem we need to create a defensive copy of that field and return that field every time it is requested.
4. If a mutable object passed to the constructor must be assigned to a
field create a defensive copy of it
The same problem happens if you hold a reference passed to the constructor because it is possible to change it. So holding a reference to an object passed to the constructor can create mutable objects. To solve this problem it is necessary to create a defensive copy of the parameter if they are mutable objects.
Note that if a field is a reference to an immutable object is not necessary to create defensive copies of it in the constructor and in the getter methods it is enough to define the field as final and private.
5. Don't allow subclasses to override methods
If a subclass override a method it can return the original value of a mutable field instead of a defensive copy of it.
To solve this problem it is possible to do one of the following:
Declare the immutable class as final so it can't be extended
Declare all methods of the immutable class final so they can't be overriden
Create a private constructor and a factory to create instances of the immutable class because a class with private constructors can't be extended
If you follow those simple rules you can freely share your immutable objects between threads because they are thread safe!
Below are few notable points:
Immutable objects do indeed make life simpler in many cases. They are especially applicable for value types, where objects don't have an identity so they can be easily replaced and they can make concurrent programming way safer and cleaner (most of the notoriously hard to find concurrency bugs are ultimately caused by mutable state shared between threads).
However, for large and/or complex objects, creating a new copy of the object for every single change can be very costly and/or tedious. And for objects with a distinct identity, changing an existing objects is much more simple and intuitive than creating a new, modified copy of it.
There are some things you simply can't do with immutable objects, like have bidirectional relationships. Once you set an association value on one object, it's identity changes. So, you set the new value on the other object and it changes as well. The problem is the first object's reference is no longer valid, because a new instance has been created to represent the object with the reference. Continuing this would just result in infinite regressions.
To implement a binary search tree, you have to return a new tree every time: Your new tree will have had to make a copy of each node that has been modified (the un-modified branches are shared). For your insert function this isn't too bad, but for me, things got fairly inefficient quickly when I started to work on delete and re-balance.
Hibernate and JPA essentially dictate that your system uses mutable objects, because the whole premise of them is that they detect and save changes to your data objects.
Depending on the language a compiler can make a bunch of optimizations when dealing with immutable data because it knows the data will never change. All sorts of stuff is skipped over, which gives you tremendous performance benefits.
If you look at other known JVM languages (Scala, Clojure), mutable objects are seen rarely in the code and that's why people start using them in scenarios where single threading is not enough.
There's no right or wrong, it just depends what you prefer. It just depends on your preference, and on what you want to achieve (and being able to easily use both approaches without alienating die-hard fans of one side or another is a holy grail some languages are seeking after).
Don't provide "setter" methods — methods that modify fields or
objects referred to by fields.
Make all fields final and private.
Don't allow subclasses to override methods. The simplest way to do this is to declare the class as final. A more sophisticated approach is to make the constructor private and construct instances in factory methods.
If the instance fields include references to mutable objects, don't allow those objects to be changed:
Don't provide methods that modify the mutable objects.
Don't share references to the mutable objects. Never store references to external, mutable objects passed to the constructor; if necessary, create copies, and store references to the copies. Similarly, create copies of your internal mutable objects when necessary to avoid returning the originals in your methods.
First of all, you know why you need to create immutable object, and what are the advantages of immutable object.
Advantages of an Immutable object
Concurrency and multithreading
It automatically Thread-safe so synchronization issue....etc
Don't need to copy constructor
Don't need to implementation of clone.
Class cannot be override
Make the field as a private and final
Force callers to construct an object completely in a single step, instead of using a no-Argument constructor
Immutable objects are simply objects whose state means object's data can't change after the
immutable object are constructed.
please see the below code.
public final class ImmutableReminder{
private final Date remindingDate;
public ImmutableReminder (Date remindingDate) {
if(remindingDate.getTime() < System.currentTimeMillis()){
throw new IllegalArgumentException("Can not set reminder" +
" for past time: " + remindingDate);
}
this.remindingDate = new Date(remindingDate.getTime());
}
public Date getRemindingDate() {
return (Date) remindingDate.clone();
}
}
Minimize mutability
An immutable class is simply a class whose instances cannot be modified. All of the information contained in each instance is provided when it is created and is fixed for the lifetime of the object.
JDK immutable classes: String, the boxed primitive classes(wrapper classes), BigInteger and BigDecimal etc.
How to make a class immutable?
Don’t provide any methods that modify the object’s state (known as mutators).
Ensure that the class can’t be extended.
Make all fields final.
Make all fields private.
This prevents clients from obtaining access to mutable objects referred to by fields and modifying these objects directly.
Make defensive copies.
Ensure exclusive access to any mutable components.
public List getList() {
return Collections.unmodifiableList(list); <=== defensive copy of the mutable
field before returning it to caller
}
If your class has any fields that refer to mutable objects, ensure that clients of the class cannot obtain references to these objects. Never initialize such a field to a client-provided object reference or return the object reference from an accessor.
import java.util.Date;
public final class ImmutableClass {
public ImmutableClass(int id, String name, Date doj) {
this.id = id;
this.name = name;
this.doj = doj;
}
private final int id;
private final String name;
private final Date doj;
public int getId() {
return id;
}
public String getName() {
return name;
}
/**
* Date class is mutable so we need a little care here.
* We should not return the reference of original instance variable.
* Instead a new Date object, with content copied to it, should be returned.
* */
public Date getDoj() {
return new Date(doj.getTime()); // For mutable fields
}
}
import java.util.Date;
public class TestImmutable {
public static void main(String[] args) {
String name = "raj";
int id = 1;
Date doj = new Date();
ImmutableClass class1 = new ImmutableClass(id, name, doj);
ImmutableClass class2 = new ImmutableClass(id, name, doj);
// every time will get a new reference for same object. Modification in reference will not affect the immutability because it is temporary reference.
Date date = class1.getDoj();
date.setTime(date.getTime()+122435);
System.out.println(class1.getDoj()==class2.getDoj());
}
}
For more information, see my blog:
http://javaexplorer03.blogspot.in/2015/07/minimize-mutability.html
an object is called immutable if its state can not be changed once created. One of the most simple way of creating immutable class in Java is by setting all of it’s fields are final.If you need to write immutable class which includes mutable classes like "java.util.Date". In order to preserve immutability in such cases, its advised to return copy of original object,
Immutable Objects are those objects whose state can not be changed once they are created, for example the String class is an immutable class. Immutable objects can not be modified so they are also thread safe in concurrent execution.
Features of immutable classes:
simple to construct
automatically thread safe
good candidate for Map keys and Set as their internal state would not change while processing
don't need implementation of clone as they always represent same state
Keys to write immutable class:
make sure class can not be overridden
make all member variable private & final
do not give their setter methods
object reference should not be leaked during construction phase
The following few steps must be considered, when you want any class as an immutable class.
Class should be marked as final
All fields must be private and final
Replace setters with constructor(for assigning a value to a
variable).
Lets have a glance what we have typed above:
//ImmutableClass
package younus.attari;
public final class ImmutableExample {
private final String name;
private final String address;
public ImmutableExample(String name,String address){
this.name=name;
this.address=address;
}
public String getName() {
return name;
}
public String getAddress() {
return address;
}
}
//MainClass from where an ImmutableClass will be called
package younus.attari;
public class MainClass {
public static void main(String[] args) {
ImmutableExample example=new ImmutableExample("Muhammed", "Hyderabad");
System.out.println(example.getName());
}
}
Commonly ignored but important properties on immutable objects
Adding over to the answer provided by #nsfyn55, the following aspects also need to be considered for object immutability, which are of prime importance
Consider the following classes:
public final class ImmutableClass {
private final MutableClass mc;
public ImmutableClass(MutableClass mc) {
this.mc = mc;
}
public MutableClass getMutClass() {
return this.mc;
}
}
public class MutableClass {
private String name;
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
}
public class MutabilityCheck {
public static void main(String[] args) {
MutableClass mc = new MutableClass();
mc.setName("Foo");
ImmutableClass iMC = new ImmutableClass(mc);
System.out.println(iMC.getMutClass().getName());
mc.setName("Bar");
System.out.println(iMC.getMutClass().getName());
}
}
Following will be the output from MutabilityCheck :
Foo
Bar
It is important to note that,
Constructing mutable objects on an immutable object ( through the constructor ), either by 'copying' or 'cloing' to instance variables of the immutable described by the following changes:
public final class ImmutableClass {
private final MutableClass mc;
public ImmutableClass(MutableClass mc) {
this.mc = new MutableClass(mc);
}
public MutableClass getMutClass() {
return this.mc;
}
}
public class MutableClass {
private String name;
public MutableClass() {
}
//copy constructor
public MutableClass(MutableClass mc) {
this.name = mc.getName();
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
}
still does not ensure complete immutability since the following is still valid from the class MutabilityCheck:
iMC.getMutClass().setName("Blaa");
However, running MutabilityCheck with the changes made in 1. will result in the output being:
Foo
Foo
In order to achieve complete immutability on an object, all its dependent objects must also be immutable
From JDK 14+ which has JEP 359, we can use "records". It is the simplest and hustle free way of creating Immutable class.
A record class is a shallowly immutable, transparent carrier for a fixed set of fields known as the record components that provides a state description for the record. Each component gives rise to a final field that holds the provided value and an accessor method to retrieve the value. The field name and the accessor name match the name of the component.
Let consider the example of creating an immutable rectangle
record Rectangle(double length, double width) {}
No need to declare any constructor, no need to implement equals & hashCode methods. Just any Records need a name and a state description.
var rectangle = new Rectangle(7.1, 8.9);
System.out.print(rectangle.length()); // prints 7.1
If you want to validate the value during object creation, we have to explicitly declare the constructor.
public Rectangle {
if (length <= 0.0) {
throw new IllegalArgumentException();
}
}
The record's body may declare static methods, static fields, static initializers, constructors, instance methods, and nested types.
Instance Methods
record Rectangle(double length, double width) {
public double area() {
return this.length * this.width;
}
}
static fields, methods
Since state should be part of the components we cannot add instance fields to records. But, we can add static fields and methods:
record Rectangle(double length, double width) {
static double aStaticField;
static void aStaticMethod() {
System.out.println("Hello Static");
}
}

Is there any purpose to make private class variable to public

Hello I am curious to know that Is there any purpose to make private class variable to public in Java.
public class XYZ {
public String ID;
public ABC abc;
private class ABC {
public boolean isExist;
}
}
Thanks in advance.
Yes, there's a purpose. If you do that then those program elements which can access the class can manipulate that variable directly. Otherwise (say if the variable is private), those elements would still be able to access the class but won't be able to manipulate the variable (unless you provide a getter/setter for it).
Think about it this way: the class modifier defines the level of access to the class, the variable modifier then defines the level of access to the variable itself (for those elements which can access the class).
This is sometimes done for data-only classes. For example, this is sometimes done to represent the models stored in databases (see Objectify for a real example of how this is used, in conjunction with annotations, to represent the database models that are stored in an App Engine database).
That being said, this sort of thing makes for a very poor API. If you do this, I'd suggest doing it with classes that are either package-level access or in private nested classes, only. When exposing functionality or data to code outside your package, it is generally better to do it with a carefully designed interface that would allow you to change the implementation if your underlying structure were to change.
That is to make isExist visible to XYZ class.
Note, ABC is only visible to XYZ and not to any outside classes and its variable is public so you can have access to it. private has not meaning to XYZ, only outside classes
From inside XYZ,
ABC abc = new ABC(); //can only be accessed by XYZ.
abc.isExists = true; //can only be accessed by XYZ
Making isExist public means you do not care about encapsulating (prevent it from unwanted manipulation from outside) it. If you make it private, you will need a get accessor to expose it
private class ABC {
private boolean _isExist; //only through accessors
public boolean isExist()
{
return _isExist;
}
}
You can do either of the following two things to your class instance variables:
THING # 1: Keep your instance variables private. Then have public getter and setter methods to get and set the value of that variable. The good thing about it is that you get to put checks inside the setter method. For example, lengths can never be negative. So, you can't just make lengths public and let anyone assign it whatever value they want. You need to make sure the value being assigned to it is not negative. So:
class myClass {
private int length;
public void setLength(int i) {
if ( i > 0 ) {
length = i;
}
}
}
Also, you can make your instance variables read-only, write-only, or read-and-write, depending on the availability of getter and setter methods for that private variable.
THING # 2 : If you don't need any restrictions on the value of your instance variable, and you want it to neither be read-only nor write-only, then it's fine to keep that variable public. For example: babies can have any name - no restrictions:
class Baby {
public name;
}
class Mother {
public void nameTheBaby() {
Baby baby = new Baby();
baby.name = "Sarah";
}
}

What is the advantage of having a private attribute with getters and setters? [duplicate]

This question already has answers here:
Why use getters and setters/accessors?
(37 answers)
Closed 9 years ago.
In object oriented programming, I used to have this question and I still do :
What would be the benefit of declaring a class member as private if we
will create for it a public getter and a public setter?
I don't see any difference at the security level between the case above and the case of declaring the class member as public.
Thanks!
Encapsulation provides data hiding and more control on the member variables. If an attribute is public then anyone can access it and can assign any value to it. But if your member variable is private and you have provided a setter for it. Then you always have an option to put some constraints check in the setter method to avoid setting an illogical value.
For example a class with public member only :
class MyClass {
public int age;
}
public MyClassUser {
public static void main(String args[]) {
MyClass obj = new MyClass();
obj.age = -5 // not a logical value for age
}
}
Same class with private member and a setter:
class MyClass {
private int age;
public void setAge(int age) {
if(age < 0) {
// do not use input value and use default
} else {
this.age = age;
}
}
}
If your class has no invariants to maintain then writing public getters and setters for a private data member is pointless; you should just use a public data member.
On the other hand, if you do have invariants to maintain then using a setter can allow you to restrict the values that can be assigned to the data member.
Note that just because you have a data member doesn't mean you have to write any getters or setters for it.
Pet peeve: "but what if the internals change?" It doesn't matter. You had a getName function that returned a std::string const&. Getters reduce encapsulation because they constrain your choices when changing the implementation later on.
Quick (and a bit silly) example:
class Foo {
private int age = -1; // unset value
public setAge(int a) {
if (a < 0) {
throw new IllegalArgumentException("Invalid age "+a);
}
age = a;
}
public getAge() {
if (age < 0) {
throw new InvalidStateException("Age was not previously set.")
}
return age;
}
}
In short: you gain control and you can assure values are correct. It's called encapsulation.
http://en.wikipedia.org/wiki/Encapsulation_%28object-oriented_programming%29
You could later change the internal representation of the class member, add functionality to the getter and setter (such as notifying an Observer), all without changing the interface (the public getter and setter).
Your question is indeed the difference between Fields and Properties. Fileds are usually private and properties do expose them. Bellow is a quote of a brilliant answer on SO:
Properties expose fields. Fields should (almost always) be kept
private to a class and accessed via get and set properties. Properties
provide a level of abstraction allowing you to change the fields while
not affecting the external way they are accessed by the things that
use your class.
What is the difference between a Field and a Property in C#?
In C# automatic properties will create a filed for you without having to manually declare it:
public Prop { get; set; }
public Prop { public get; private set; }
public Prop { private get; public set; }
// etc, you can specify access modifier as per your need
I don't see any difference at the security level between the case above and the case of declaring the class member as public.
Immediate question are :
1)What if you want to check some conditions,While setting the value ?
2)What if the subclassess want to return or set something else,by ovveridng that method ?
Other reason:Why getter and setter are better than public fields in Java
If you have a data transfer object, with limited scope and by design it should have no logic associated with it, I don't see a value in getters and setters.
However, if you have a component which may or may not have some logic associated with it or it could be widely used, then it makes sense to hide the details of how the data is stored. Initially it might appear that all the getters and setters are trivial and just fill up you class, but over time you might add validation to the setters and even change the getters. e.g. you might drop a field (and return a constant in future), store the data in a delegated object or compute the value from other fields.
Beside the encapsulation, consider a situation where your setter is not simply sets a value.
What if you're using it in many classes? And now you realize you want to change the functionality of it? You'll have to change it in whole places where you manually set it. Whereas if you had a setter life would have been easier.
As with any encapsulation: it hides implementation details. This allows you to control access and provide a stable interface even when the internals change.
Setter controlling access
class Person //version 1.0
{
std::string name;
public:
std::string getName() const { return name; }
void setName(const std::string &newName)
{
if (!newName.empty()) //disallow empty names
name = newName;
}
};
Getter useful during API evolution
class Person //version 1.1
{
std::string firstName;
std::string lastName;
public:
std::string getFirstName() const { return firstName; }
void setFirstName(const std::string &newFirstName)
{
firstName = newFirstName;
}
std::string getLastName() const { return lastName; }
void setLastName(const std::string &newLastName)
{
if (!newLastName.empty()) //disallow empty last names
firstName = newFirstName;
}
std::string getName() const
{
std::ostringstream s;
if (!firstName.empty())
s << fistName << ' ';
s << lastName;
return s.str();
}
void setName(const std::string &newName)
{
setFirstName(splitUntilLastSpace(newName));
setLastName(splitFromLastSpace(newName));
}
};
Accessor methods provide a single point of update for a given field. This is beneficial because validation logic or other modifications to the field can be controlled via the single method as opposed to having the field directly accessed throughout the code base.
See this IBM document which details more benefits: http://www.ibm.com/developerworks/java/library/ws-tip-why.html
If the public getter and public setter are just to return the value of the private property and to change its value, then I see no difference.
However, you are implementing encapsulation, so in a later moment you can implement a different behavior, including argument check for setter or write-only/read-only properties, for instance.
Actually, if you're developping alone on a small project and you won't reuse your code, it's kinda useless, but it's mostly a good habbit.
But, in team developpment, you may need to have some control on modification, and you can do it through the getters and setters.
Moreover, in some classes, you'll only have getters, as the setters will be done by the constructor, or via some other functions.
Declaring variables as private is called as Encapsulation in Java.
Here are few advantages of using Encapsulation while writing code in Java or any Object oriented programming language:
Encapsulated Code is more flexible and easy to change with new requirements.
Encapsulation in Java makes unit testing easy.
Encapsulation in Java allows you to control who can access what.
Encapsulation also helps to write immutable class in Java which are a good choice in multi-threading
environment.
Encapsulation reduce coupling of modules and increase cohesion inside a module because all piece of one thing
are encapsulated in one place.
Encapsulation allows you to change one part of code without affecting other part of code.
one more advantage is
Making variables private in java and providing getter and setter for them makes your class compatible Java bean naming convention
I have only one thing to add to the excellent answers that this post have so far.
Sometimes a class attribute could have more than one Getter or Setter, let's illustrate with a silly short example:
class Angle
{
public:
void Set(MyAngleTypedef a_value) { m_angle = a_value; }
// Note the 'Radians' type
void SetRadians(Radians a_value) { m_angle = ConvertRadiansToOurUnit(a_value); }
// Note the 'Degrees' type
void SetDegrees(Degrees a_value) { m_angle = ConvertDegreesToOurUnit(a_value); }
void Get(MyAngleTypedef a_value) const { return m_angle; }
// Note the 'Radians' type
Radians GetRadians(Radians a_value) const { return ConvertOurUnitToRadians(m_angle); }
// Note the 'Degrees' type
Degrees GetDegrees(Degrees a_value) const { return ConvertOurUnitToDegrees(m_angle); }
private:
// Raw value of the angle in some user-defined scale.
MyAngleTypedef m_angle;
}
Is meaningless to store the value more than once for each unit type which you want to work, so the Getters and Setters will provide an interface that makes the class able to work with different units.
IMHO, when a object contains active attributes (attributes that must do some work after or before it is assigned or accessed) it must be a class with only the essential Getters and Setters (the private attributes that doesn't need accessed outside the class, obviously doesn't need public Getters and Setters).
In the other hand if an object conains only passive attributes (attributes that doesn't need extra work when assigned or accessed) it must be a struct and therefore all his attributes would be public accesible without Getters and Setters.
Note that this answer is from the c++ point of view, check this question for more information.
One of the most important concepts of Object Oriented Programming is encapsulation. You encapsulate data and the methods that act on that data together. Ideally, data should be accessed only via its related methods. And the state of data should be "queried" by other objects via these methods. Making a variable public will result in that variable being directly available to all other objects breaking encapsulation.

Categories

Resources