I have been doing assignments for college projects. At one point, I am getting confused at what is actually the use of getter and setter when you can actually use constructor methods to achieve the same results. I have searched and found many answers but not satisfactory explanation.
I have laptop.java as follows
public class laptop {
private String model;
public laptop(String brand){
model=brand;
}
public String toString(){
return "Laptop Brand is: "+ model;
}
}
and the laoptopRecords.java that is calling constructor as
public class laptopRecords {
public static void main(String[] args) {
// TODO Auto-generated method stub
laptop laptop1=new laptop("Dell");
System.out.println(laptop1);
}
}
Here I am not using the getter and setter methods and I get desired result for every laptop object.
If I do in another way using getter and setter methods in laptopRecord.java as follows, I get the same result. But I am not getting what is use of getter and setter methods if actually we can achive the results with constructor as well.
laptop.java with getter and setter
public class laptop {
private String model;
public laptop(String brand){
model=brand;
}
public void setlaptop(String brand){
model=brand;
}
public String getlaptop(){
return model;
}
public String toString(){
return "Laptop Brand is: "+ model;
}
}
Getters are always nice. If you forgot what brand you set at creation, it would be nice to have a way of getting it out of that object. What if you got that object from somewhere else? Figuring out the brand using a getter is easy that way. But getters should only be available on directly exposed values. No need to create a getter for internalVersionString if it should not be publically known. But having a getter for colour would be nice... after all, you can see the colour by looking at the laptop (which is a bad analogy for OOP, but it's fitting here IMHO).
Regarding setters... if you have only one attribute, there is not much of a (visible) difference indeed. But what lies beyond that is a deeper subject... mutability. Of course, using a constructor has a greater overhead than simply setting the attribute (getting memory for a whole new object vs. getting memory for a string).
A nice example of not using setters is the String class in Java. A Java String is immutable; once created, it cannot be changed whatsoever. If you want to replace characters or remove some parts, what you get is not a changed String, but instead a brand new String with the desired changes made. But what if you had a class called TextDocument, that contained a whole file's worth of data? Having no ability to replace parts of that one without creating a whole new TextDocument could be hindering.
Having setters automatically means your object is mutable; that means, your object is not fixed upon creation, but can be changed later on. An ArrayList would be a nice example here. You'd certainly not want to allocate a whole new list only to change a single value.
The difference between mutable and immutable are not as clear when using simple cases like your laptop class. Using immutable classes comes in handy when doing parallel work, using mutable classes comes in handy when handling big objects with a large amount of memory needed to allocate.
There's no one-fits-all solution for that problem. But for exposed attributes which should be directly changeable, a setter would be convenient instead of having to construct a whole new object. Imagine a class with multiple attributes... taking your laptop for example, having a brand, a size, a colour and whatnot. If you just want to change the colour, having to construct a new laptop and copying over all the other attributes would be tedious, wouldn't it? A setter would make life easier for you in that case. Just call yourLaptop.setBrand("Dill"); and continue using that laptop. No reason to spend 500 bucks (or rather... bytes) for another one.
I tell you an easy way:
getters() and setters():
actually getters() and setters available in POJO/Bean classes.
The main reason used for getters() setters() in java classes is To get the Java Encapsulation Mechanism.
In POJO/Bean classes we declare all attributes as a private. that means these class attributes can't use in other classes and packages, so in this, we can achieve Encapsulation.
Constructors():
I think you know the definition of constructor, The constructor is used for initializing the attributes giving our own values rather than storing the default values
We can say another way i.e Constructor used for creating an object and setters used for changing the values inside object, getters() user for getting the values, this is only the main difference.
When you extend a class having private data members ,then getters and setters method will help you to access that data members in subclass.While constructor only initialize the data members.
Constructor is used to initialize object.
When we use parameterized constructor to pass parameter it only call once.
Means you can only pass parameter once.
if you call it more then 1 time each time a new object created in memory.
While getter and setter can be called according to your use many time to set or get values
Related
I have a class that has many settable/gettable attributes. I'd like to use reflection to set these attributes, but I have 2 questions about my implementation
Here is some stripped down code from my class
class Q {
public String question_1;
public String question_2;
public String question_3;
public String answer_1;
public String answer_2;
public String answer_3;
//etc. etc. Many String attributes
// … constructor and other stuff are omitted
// here is my method for "dynamically" setting each attribute
public void set_attribute(String a_raw_string, String my_field) {
try {
Class cls = Class.forName("com.xyz.models.Q");
Field fld = cls.getField(my_field);
fld.set(this, a_raw_string);
}
catch (Throwable e) {
System.err.println(e);
}
}
I then set various fields like this:
Q q = new Q();
q.set_attribute("abcde", "question_1");
q.set_attribute("defgh", "question_2");
// etc.
This works (i.e., the instance variables are set when I call set_attribute.
However, they only work when the instance variables are declared public. When they are declared private I get a NoSuchFieldException
QUESTION 1: Why do I get that error when the fields are private? My naive assumption is that since the set_attribute function is part of the class, it should have unfettered access to the instance variables.
QUESTION 2: I think I may be overthinking this problem (i.e., I shouldn't be using reflection to set variables in this way). Is there a more recommended approach?
The reason that I want to use reflection is because it's a pain in the ass to declare a ton of setter methods…so I'm wondering if someone has solved this annoyance in a better way.
Thanks!
I think I may be overthinking this problem (i.e., I shouldn't be using reflection to set variables in this way)
Yep. Reflection is fairly slow and should only be used as a last resort. If this is simply to avoid having so much redundant code, consider using automatic code generation. For pure data objects, I would strongly recommend using protocol buffers; it will generate the getters / setters (you only need to declare the fields). Plus it allows for easy communication of the data between C++, Java, and Python.
If you have a class that has a lot of fields but isn't a pure data object... well
You should consider whether all the fields should be mutable. (Do you really need setters?)
Whether the fields should even be visible. (Do you need any accessors at all?)
It is often a good idea to make fields "final", initialize them in the constructor(s), and provide no access or provide limited access through an implemented interface.
Using setter methods is the accepted way to set values for class member variables, reflection should definitely not be used for that as the code will be harder to understand and run much more slowly.
Most IDEs (eg Eclipse or NetBeans) include tools for automatically creating getter and setter methods for a class's fields.
When they are private you need to call fld.setAccessible(true);
Yes, why don't you just set the fields directly and avoid reflection? It doesn't look like you're doing anything dynamic. It's just that they are private -- why? Perhaps you mean to expose getters/setters and make the fields private? If so, then you should just invoke the public setters.
I'm currently learning Java and learning about encapsulation and I'm unsure which of the following is a better practice:
Use a getter to return a field value from one class to another and then print it through a method in another class.
Call a method in a class from another class to print the value of the field.
The value isn't manipulated, only shown through System.out.println();
Any advice would be appreciated :)
EDIT: One class (Person) holds information about people, such as name, age, weight etc. and another class (Directory) has a method used to search through a LinkedList of people to find a object with a matching age. If a person is found, then the method prints out the name of the person.
Encapsulation is all about maintaining a separation of concerns, the core idea of which is that one class should know as little as possible about how other classes work, partly so that you can make changes to those classes without having to change other classes that interact with them.
Broadly: As a rule of thumb, you want each of your classes to do "it's own little thing" - to have its own little concern, with all the logic that goes into doing that little thing encapsulated in private methods of that class. If other classes, in the course of doing their own little things, need to know things from the first class, then you provide getter methods in that class that expose those things without exposing the details of how they are implemented internally.
With respect to your question specifically, the options you mention are actually the same thing: A getter is a method that gets called by other classes to return the value of a field. The advantage of such a method is that it encapsulates that field in the class that contains it, which can then parse/recalculate/store or otherwise interact with that field however it pleases, as long as it's getter returns the expected data type.
To illustrate, imagine you create a BankAccount class with a double balance field. You do a few tests and it seems to work fine, so you create several other classes that reference this balance field. At some point, you notice that some of your calculations are coming up a few cents off. You do some research and find out that it's a bad practice to use double to store monetary values, and that you should be using a class called BigDecimal instead.
If your other classes accessed your balance field directly, they would all have to change (and all would have to import BigDecimal even though they never use it directly) in order to facilitate this change. On the other hand, if they access an account's balance by way of a getter method, you can change the type of balance to BigDecimal in BankAccount
while leaving the return type of getBalance() as double, by calling BigDecimal's toDouble() method to return the double value your other classes expect: None of your other classes will ever know you've changed the data type.
Another way of stating the idea of separation of concerns is to say that each class should have a single reason to change (this is the single responsibility principle referenced in #GregKopff's comment): Needing to change the data type of the balance field is a valid reason for BankAccount to change, but would it be a valid reason or all the other classes that interact with it to change? Should you have to change your BankAccountHolder or BankEmployee class because a technical detail in the Account class changed?
This might not seem to answer your question directly, but I think the only answer to this question in general is to illustrate the question you should ask yourself to answer it each time you come across it... which will happen just about every time you write a class.
If my illustration is unclear, please let me know how I can clarify it: You've asked an important question, and it's important that you grasp the answer to it (as well as what you're asking.)
My suggestion would be to use Getters and Setters. Getters are public methods which returns the value of their respective fields. Setters are public methods which sets the value of their respective fields.
public class YourClass {
private String yourMember;
public String getYourMember() {
return this.yourMember;
}
public void setYourMember(String member) {
this.yourMember = member;
}
}
And use these methods to get or set the values of the variable.
public class AnotherClass {
public void someMethod() {
YourClass yc = new YourClass();
yc.setYourMember( "Value" );
System.out.println( yc.getYourMember() );
}
}
But if printing the value is part of the behavior of the class, then it would be better if you add a printYourMember() method also to your class. This really is a context sensitive question. Without knowing the actual context, I can not give more specific answer.
Good Luck!
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Are Getters and Setters evil?
I can't find a logical reason behind having a private variable with a getter and a setter that does nothing but directly handling the value being preferable to having a public variable.
Am I missing something?
Because,
Validation is one reason. Keeping the field name out of the public API also allows you to change it later without breaking the API. And it allows you to change the class later in other ways as well, e.g. moving the field to some other class (so that the public setter would call a setter in a different class). Having the setter called also allows you to do other things, e.g. notify interested other components of the change of value. None of this would be possible if the field was accessed directly.
They are preferred to future proof the code. In the future if you want to eliminate the variable or use another variable to derive this variables value - the change is simpler. You just need to change the getter/setter, the rest of the code remains unaffected. This is not the case with direct access to the variable.
As #user370305 already mentioned one reason is validation.
Other reason is types conversion. Setter may accept string and parse it to integer.
Yet another reason is data encapsulation. It is not necessarily to have a simple filed stored in the same class. Method setName(String) of class Person may store the name in more complicated data structure. Using simple field does not allow you to change the internal implementation of class Person without affecting code that uses it.
EDIT:
yet another technical reason.
It is much easier to discover and debug code with getters and setters. If some field is changed unexpectedly you can just toggle break point into appropriate setter and find the problem very quickly. If this field is public and you have 1000 references to this field you theoretically have to put 1000 breakpoints in all these places.
1. Encapsulation has different use in different context, In design patterns its like behaviors that keeps changing needs to be encapsulated in abstract class, or interface.
2. Having private instance variable and public getter setter is b
3. Its mainly done to Validate the input from the user... Setting the value to an instance variable directly is dangerous.
Eg:
int dogAge;
System.out.println("My dogs age is :"+dogAge);
Now what if someone gives a negative age... then.......???
So we must do it this way...
int dogAge;
public void setAge(int age){
if (age>0){
dogAge = age;
}
else{
System.out.println("Not a valid age");
}
}
public int getAge(){
return dogAge;
}
System.out.println("My dog age is :"+ getAge());
Its simple .. if you make those variable public then you give rights for ading any values to them .
But if you do that via getter or setter ... you can put checks over it and control the input or conversion without letting the end user know that
eg :
getName(){
return firstName+lastName;
}
or
getData(){
// code to convert byte to Mb or whatever you like to represent
}
Use of accessors to restrict direct access to field variable is preferred over the use of public fields, however, making getters and setter for each and every field is overkill and considerd as not a good practice. It also depends on the situation though, sometimes you just want a dumb data object. Accessors should be added for field where they're really required. See this link to know more about it Getter Setter: To Use or Not to Use.
I can't find a logical reason behind having a private variable with a getter and a setter that does nothing but directly handling the value being preferable to having a public variable.
Consider that any additional code that you put into getters and setters adds to complexity and also needs to be tested. For a small system which is fully controlled by you, there may be little benefit in using getters and setters. Use your professional judgement. You may not need the future proofing and added complexity. Or it may be more important to you to have the efficiency and simplicity of direct access.
Personally, I think that getters and setters are over-used. For a small system which is fully controlled by you, direct access may be the way to go.
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
What is the point of setters and getters in java?
I have a question about set method. Please provide some details if possible.
I want to know why do we use set method with class name.
public class Mymainclass {
Private class ClassC {
Private Mysecondclass sec = null;
public void setMymainclass(Mysecondclass second){
Mymainclass.sec= second;
}
}
}
Is it just setting the sec variable value ? if yes why there is class name with set?
It seems like you are confusing a "class constructor" with a "setter method" in a class.
The primary reason for a constructor is to intialize the class variables
The primary reason for a setter method is to access private variables inside the clas
So in your case the name of the method should be "setSec" rather than setMainClass.
That is if you would like to modify the private variable "sec" after you have initialized the class then you can choose to use a setter method.
On the other hand you can also not use a setter method and just have the sec variable be initialized when the class is first created. To do that you will have to create a constructor.
Your constructor for this class will look like this:
Mymainclass(Mysecondclass sec){
this.sec = sec;
}
This way you can pass is a Mysecondclass object as soon as you create a new instance of Mymainclass.
Also try to make sure when you label classes to make each word in the class name to have its first letter capital like this: MySecondClass and MyMainClass!!
Firstly your method should be called "setSeconds" if you follow good practice. Just think how confusing it would be if you added a minutes member to your class.
There are two main reasons for coding setters and getters.
The first is purly pragmatic. If you want to invoke the magic of introspection and java beans then you need to follow these conventions. There are several libraries/APIs like FreeMarker that absolutly depend on haveing getter and setter methods in your class.
The second has more to do with good design. Consider thet you have a public member called seconds. Any user of you class could set this by coding.
instanceOfYourClass.seconds = 60;
This is just fine except maybe you want to impose an arbitary limit of 42 seconds on this value. To validate the value and set it a max of 42 seconds you now need a method to do this. So every user of you class must now change thier code to:-
instanceOfYourClass.setSeconds(60);
So by building in getters and setters from the start you are building in both the flexibilty to do more exotic things within your class, while at the same time providing a stable interface to your class users which wont rquire them to change thier code every time there is a small change in functionality.
I think part of the source of your confusion is that the example you gave is bad code! You don't name a setter based on the class of its argument, you named it based on the property of the object that you're setting. e.g., the canonically 'correct' version of your example would be:
public class Mymainclass {
private Mysecondclass sec= null;
public void setSec(Mysecondclass second){
this.sec= second;
}
}
Having setters that map to property names allows all kinds of different frameworks from UI to persistence and all in between to manipulate your objects in an abstract way. If you tell, for example, your database layer that the property named 'sec' maps to a particular database column, it can use reflection to find the method named "setSec" and set it for you!
The idea of having lots of methods just named 'set' also breaks down when you have lots of properties of the same type, lots of Strings, lots of BigDecimals, whatever. It would be really wierd if there were two standards to only use 'set' when you can and use the property name when you have to. (and you'd find yourself refactoring away those 'set' only methods awfully often.)
In object oriented programming, a good practice is to expose getters and setters to allow other class to interact with a class content instead of making member variables public.
Even if most of the time, at least in the very first version of the class, there won't be much more there than the actual assignment statement, this will allow you to add other behaviors later:
add logging traces to know when and how a new value has been set
do some controls/transformations on the value that is passed before really assign it (what if the other class provided null ?)
trigger some other actions that could be necessary whent this new assignment is done
...
I have a class that has many settable/gettable attributes. I'd like to use reflection to set these attributes, but I have 2 questions about my implementation
Here is some stripped down code from my class
class Q {
public String question_1;
public String question_2;
public String question_3;
public String answer_1;
public String answer_2;
public String answer_3;
//etc. etc. Many String attributes
// … constructor and other stuff are omitted
// here is my method for "dynamically" setting each attribute
public void set_attribute(String a_raw_string, String my_field) {
try {
Class cls = Class.forName("com.xyz.models.Q");
Field fld = cls.getField(my_field);
fld.set(this, a_raw_string);
}
catch (Throwable e) {
System.err.println(e);
}
}
I then set various fields like this:
Q q = new Q();
q.set_attribute("abcde", "question_1");
q.set_attribute("defgh", "question_2");
// etc.
This works (i.e., the instance variables are set when I call set_attribute.
However, they only work when the instance variables are declared public. When they are declared private I get a NoSuchFieldException
QUESTION 1: Why do I get that error when the fields are private? My naive assumption is that since the set_attribute function is part of the class, it should have unfettered access to the instance variables.
QUESTION 2: I think I may be overthinking this problem (i.e., I shouldn't be using reflection to set variables in this way). Is there a more recommended approach?
The reason that I want to use reflection is because it's a pain in the ass to declare a ton of setter methods…so I'm wondering if someone has solved this annoyance in a better way.
Thanks!
I think I may be overthinking this problem (i.e., I shouldn't be using reflection to set variables in this way)
Yep. Reflection is fairly slow and should only be used as a last resort. If this is simply to avoid having so much redundant code, consider using automatic code generation. For pure data objects, I would strongly recommend using protocol buffers; it will generate the getters / setters (you only need to declare the fields). Plus it allows for easy communication of the data between C++, Java, and Python.
If you have a class that has a lot of fields but isn't a pure data object... well
You should consider whether all the fields should be mutable. (Do you really need setters?)
Whether the fields should even be visible. (Do you need any accessors at all?)
It is often a good idea to make fields "final", initialize them in the constructor(s), and provide no access or provide limited access through an implemented interface.
Using setter methods is the accepted way to set values for class member variables, reflection should definitely not be used for that as the code will be harder to understand and run much more slowly.
Most IDEs (eg Eclipse or NetBeans) include tools for automatically creating getter and setter methods for a class's fields.
When they are private you need to call fld.setAccessible(true);
Yes, why don't you just set the fields directly and avoid reflection? It doesn't look like you're doing anything dynamic. It's just that they are private -- why? Perhaps you mean to expose getters/setters and make the fields private? If so, then you should just invoke the public setters.