Related
I'm a junior developer (currently exercise Java) and I have one question about the correctness of my code, here is an example:
I am writing a simple MMO-game representation on Java, I have 2 classes (Character and spell).
Character has properties (mName, mHealth and mEnergy), Spell class has properties (mSpellName, mSpellCost, mSpellDamage). And Spell class also have a method called execute, here is a code
public void spellExecute(Character caster, Character target) {
caster.mEnergy -= this.spellCost;
target.mHealth -= this.spellDamage
}
This construction implies that Character fields are public and can be accessed directly, but in some examples I seen that all fields must be private and can be accessed only via get/set methods. My question is: Which way is more correct, in general? It's important to me because I wanna write a good code :)
Generally, you would use get/set methods, because they allow the class to control access, via those methods
Any other class which uses your class, should only be able to access and change your fields in the way you describe.
For example let's look at a simple (oversimplified) fuel pump
class Pump
{
constant int PRICE_PER_LITRE = 100; //in pence
private int litresDispensed;
private bool nozzleUp;
private int litresAvailable;
private int price; //in pence
construct()
{
litresDispensed = 0;
nozzleUp = false;
}
startFuelling()
{
nozzleUp = true;
}
stopFuelling()
{
nozzleUp = false;
}
takeFuel(int litresTaken)
{
if(nozzleUp = true)
{
litresAvailable -= litresTaken;
price += litresTaken * PRICE_PER_LITRE;
}
else
{
error("You must lift the nozzle before taking fuel!");
}
}
getPrice()
{
if(nozzleUp = true)
{
error("You can't pay until you've finished fuelling! Please return the nozzle");
}
else
{
return price;
}
}
}
Our final get method is important to ensure that the rest of the transaction is complete before the person tries to pay.
If we allowed direct access to the price, they could do it before they've finished taking fuel! And that would let them steal all our fuel.
As this shows, a get method protects the field from outside influence. It can still be manipulated, but only in the ways we want to allow it to be manipulated. Note also that there's no set method at all for this field: we don't want the user to be able to set their own price, only the one we dictate!
If you write get/set methods which only return and set the field, without any validation or checks, then you could simply make the field public (or, alternately, you need to decide whether that field should be accessed directly at all): that said, it's good practice to use get/set methods where possible, because it allows you to add validation in the future without breaking code.
You're right that it's important to write good code and at first getting the grasp of Object Oriented Programming can be a bit difficult.
In this case, I would recommend moving the spellExecute to a similar method, except on the Character class :
public void didUseSpell(Spell spell) {
this.mEnergy -= spell.spellCost;
}
public void wasHitBySpell(Spell spell) {
this.mHealth -= spell.spellDamage;
}
In your spell execute method, you would then call :
public void spellExecute(Character caster, Character target) {
caster.didUseSpell(this);
target.wasHitBySpell(this);
}
In general, there are many different was of solving this problem, and they all vary in terms of code cleanliness and verbosity. Another solution would be to create getter and setter methods for the fields that are affected by the spells.
Getters/setters are better, because it encapsulates or hides what the actual class is doing to set that data. Set the constructor private and let it initialize default values, then the user can call the set methods to set the variables.
Getters and setters with private fields is generally followed design choice. The reason is, you can guard your variables against unintentional changes from the clients using your API.
Consider this below example
public class Dummy{
public int age;
}
Now client can do this
new Dummy().age = -1
With setters and getters
public class Dummy{
private int age;
public void setAge(int age){
if (age < 0){
throw new RuntimeException("you are not allowed to do this");
}
......
}
Many frameworks for example Hibernate, IBATIS etc.. follow these naming conventions. Hope this answers your questions.
Getter and setter (Java bean) is more better.It also provide Encapsulation feature.Which is useful for hiding data.
private int id;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
Constructor is used for initialization the value when You are creating object.But If you want to set value of data after object creation then you must call setter behavior instead of call constructor.
Getters and setters are preferred - after all, why use an Object Orientated language if you're not going to use its main feature?
With setters in this situation you can easily enforce sanity rules without each caller having to duplicate the logic, e.g. - in Character try:
public void reduceMentalHealth(int val) {
if(this.mHealth > val) {
this.mHealth -= val;
} else {
this.mHealth = 0;
}
Without setters you would need this logic everywhere you changed the field. You could also include things like checking whether the Character is wearing a ring of mental invincibility in this method too :-)
Warning
You are mixing two related questions.
Questions:
[1] Should I use direct access fields, or fields access by accesors methods ( "getter" (s) and "setter" (s) ).
[2] In both cases, which access modifiers, should apply ?
Short Quick Answer
[1] Should I use direct access fields, or fields access by accesors methods ( "getter" (s) and "setter" (s) ).
Go, for the "fields access by accessor methods" a.k.a. "getter (s) and setter (s)". The other method is NOT wrong, it depends, what do you want to do.
[2] In both cases, which access modifiers, should apply ?
If you go for "plain fields", use "public", unless there is an specific reason to use "private" or "protected". If you go for "accesors methods", use "protected" for the fields, and "protected" or "public" for the accesors.
Long Boring Extended Answer
[1] Should I use direct access fields, or fields access by accesors methods ( "getter" (s) and "setter" (s) ).
Go, for the "fields access by accessor methods" a.k.a. "getter (s) and setter (s)".
The other method is NOT wrong, it depends, what do you want to do.
But, since property access can be overriden by those methods, that allows more features to be added, removed or changed by methods.
I suggest, leave "plain fields" for Data Objects.
[2] In both cases, which access modifiers, should apply ?
If you go for "plain fields", use "public", unless there is an specific reason to use "private" or "protected".
If you go for "accesors methods", use "protected" for the fields, and "protected" or "public" for the accesors.
Is not a good idea to apply "public" access for accesors' fields, because this way, you confuse yourself and other programmer users of your classes,
on which one to directly use.
Code Example:
public class ControlClass {
// example of non private field (s)
protected String controlname;
// ...
// example of non private field (s)
protected int width;
protected int height;
// ...
// example of read-only property
public final String getControlName()
{
return this.controlname;
} // String getControlName(...)
// ...
#Override
public int getWidth()
{
return this.width;
} // int getWidth(...)
#Override
public void setWidth(int newvalue)
{
this.width = newvalue;
} // void setWidth(...)
#Override
public int getHeight()
{
return this.height;
} // int getHeight(...)
#Override
public void setHeight(int newvalue)
{
this.height = newvalue;
} // void setHeight(...)
// ...
// constructor assigns initial values to properties' fields
public ControlClass(){
this.controlname = "control";
this.height = 0;
this.width = 0;
} // ControlClass(...)
// ...
} // class ControlClass
public class ButtonClass extends ControlClass {
// ...
// example of overriden public property with non public field
#Override
public int getWidth()
{
if (this.width < 5)
return 5
else
return this.width;
} // int getWidth(...)
// example of overriden public property with non public field
#Override
public void setWidth(int newvalue)
{
if (newvalue < 5)
throw new ArithmeticException("integer underflow");
this.width = newvalue;
} // void setWidth(...)
// example of overriden public property with non public field
#Override
public int getHeight()
{
if (this.height < 5)
return 5
else
return this.height;
} // int getHeight(...)
// example of overriden public property with non public field
#Override
public void setHeight(int newvalue)
{
if (newvalue < 5)
throw new ArithmeticException("integer underflow");
this.height = newvalue;
} // void setHeight(...)
// ...
// constructor assigns initial values to properties' fields
public ControlClass(){
this.controlname = "ButtonClass";
this.height = 5;
this.width = 5;
} // ButtonClass(...)
// ...
} // class ControlClass
I started to use "private" for fields, like many programmers, buy, eventually, had to change to "protected", because sometimes required to use it. directly.
Additional Comment.
I have work with other object oriented programming languages, with its own way and syntax for "properties", and that's give you another perspective.
Such as Object Pascal ( a.k.a. "Delphi" ), ECMAScript ( "Javascript" ), C++, C#. Note that Delphi and C#, supports "full properties", not just accesors methods or fields, and that's give developer another way of designing an Object and Class Oriented Software Application.
What does this has to do with Java ?
We'll when I design a Class in Java or C++, I design properties, the same way, as C# or Delphi, does, a concept that is independent of fields, or methods, even if there can be implemented by them.
Cheers.
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.
To actually understand the meaning of encapsulation, example that class private fields must be accessed through class public methods is as per definition, but actually stll it doesn't make difference as the field is still accessible as it is.
So,I think there should be some processing inside getters/setters to hide how the field is being handled. But it breaks the principal of behind pojos. How can one handle this situation?
I'm not sure what according to you is "the principle of POJOs". The following is a POJO and still hides implementation details behind getters and setters:
public class Example {
private int thousands;
private int units;
public void setValue(int value) {
thousands = value / 1000;
units = value % 1000;
}
public int getValue() {
return 1000 * thousands + units;
}
}
Encapsulation means not to expose the internals of your class.
In the Java context it means that the attributes of your class should NOT be accessible by other classes, instead your class should provide methods that will allow to access the attributes. In cases of POJO classes these methods will only allow to set (setters) and get (getters) the values of the attributes from the POJO class.
The goal of encapsulation is to protect the attributes of your class from being modified by other classes. Your class is obviously able to do whatever you want with the attributes inside your classes.
No, the field is not accessible as it is. All it takes to make a method a getter or a setter ist the proper signature.
public String getFoo() {
return null;
}
This is a perfect getter for a String foo, even though it returns null.
public void setFoo(String foo) {
// do nothing
}
This is a perfect setter for the same member, even though it does nothing.
One of the many uses of getters and setters is to restrict the value of the variable. By making the data members private and keeping the getters and setters public, the programmer can keep a check on the value of the variable. For ex:
class Employee
{
private int age;
public int getAge()
{
return this.age;
}
public void setAge(int age)
{
if(age<18 || age>60)
this.age = age;
else
System.out.println("The age of the employee should be between 18 and 60");
}
}
In this case the age of the Employee can never be more less than 18 and more than 60.
Don't know why people usually mix Data Encapsulation with Data hiding. Data encapsulation simply means grouping data together whereas data hiding is a way to store this data so others cannot know it's internal implementation.
Lets say you have a class PersonalInfo in which you have fields like name,gender,age etc. As a programmer(which you are) you will provide user some way to enter these fields, save them in your PersonalInfo object using setter methods.IF user wish to see the information you simple call getters and display information. Your implementation as in you may store this variables in a map may varry. So you can say
public void setName(String name){
SomeMap.add("name",name);
}
Note *you are the programmer and you will always know the implementatio*n. Keeping the fields private is to allow only your class methods to access your data.
Imagine it this way. User can create an object. He may set all fields using getters and setters. It may be your implementation to calculate age using DOB(Date of Birth) in which case you will not provide setter for age. In this case user cannot say myObj.age=23. This is purely your implementation.Hope this clears the confusion!
It's still accessible but you see when you use it directly (public variable) you can change the value of variable without any restriction. The advantage of using such kind of private variables with setter and getter methods is that you can write code inside the setter method to check whether the value set is in the expected range or not. Or you can even store the value in different form than the apparent view. For example you may store the value of a variable by adding offset to the value of the parameter of the setter method and in getter method you may just revert back the process(Encapsulation). When the value set is not in the expected range you may even throw exceptions.
Example1:
Here var1 is a private variable
public void setValue(int var1){
if(var1<0){
//throw exception
}
this.var1=var1;
}
Example2:
public void setValue(int var1){
this.var1=calculatesomething+var1;
}
public int getValue(){
return calculatesomething+this.var1;
}
That's the use of encapsulation.....all the best
Encapsulation is to restrict the access to the Class's variables and to regularize the way of editing them.
Class Test
{
public int a;
public Test()
{
a = 0;
}
public getA()
{
return a;
}
public setA(int a)
{
this.a = a
}
}
Class TestMain
{
main()
{
Test t = new Test();
System.out.println(t.a); // This prints 0;
int a = t.getA();
a = 10;
System.out.println(t.a); // This still prints 0;
t.a = 20;
System.out.println(t.a); // This prints 20;
}
}
In the above example the programmer may not be intentionally changing the value of t.a but the value changes.
If he really intents to change it, then he should use the setter.
Encapsulation is the feature that java provides which solves certain practical problems and helps in extensibility.
If the Test and TestMain classes are written by same person, there wont't be any confusion.
But practically that is not the case.
package cen.col.course.demo;
import java.io.Serializable;
public class Course implements Serializable {
private static final long serialVersionUID = 1L;
protected String code;
protected String title;
protected Professor professor;
public Course( String code) throws InvalidDataException {
super();
setCode(code);
}
public Course(String code, String title ) throws InvalidDataException {
this(code);
setTitle(title);
}
public Course(String code, String title, Professor professor) throws InvalidDataException {
this(code,title);
setProfessor(professor);
}
public String getCode() {
return code;
}
protected void setCode(String code) throws InvalidDataException {
if ( code == null || code.length() < 1) {
throw new InvalidDataException("Course must have a course code");
}
this.code = code;
}
public String getTitle() {
return title;
}
public void setTitle(String title) throws InvalidDataException {
if ( title == null || title.length() < 1) {
throw new InvalidDataException("Course must have a title");
}
this.title = title;
}
public Professor getProfessor() {
return professor;
}
public void setProfessor(Professor professor) {
this.professor = professor;
}
public String toString() {
String output = getCode() + ": [" + getTitle() + "]";
if (getProfessor() != null ) {
output += " is taught by " + getProfessor();
}
return output;
}
public boolean equals(Course c) {
if ( ! this.getCode().equals(c.getCode())){
return false;
}
if ( ! this.getTitle().equals(c.getTitle())){
return false;
}
// should the prof field be included in test for equality?
if ( ! this.getProfessor().equals(c.getProfessor())){
return false;
}
return true;
}
}
I have Three Questions:
I noticed my professor calling the setter methods from the constructors. I did a little searching around, and have mixed thoughts about it. Some say its okay, some say you have to be careful when your using subclasses, Is it okay to call your setters from the constructors?
The constructors throw exceptions because she is calling the setters from the constructor. Now my question is, if calling the setters from the constructors isn't a safe way of doing it, What is the proper way of doing it? My guess would be to declare a no argument constructor, and build the object using setters.
I guess doing this, is out of the question?
Course createCourse = new Course("1234","Programming 1","Pam Halpert");
I am calling the constructor that takes 3 arguments, However, if calling the setter from the constructor is not safe, how would go about doing this, and have the exception in place? Could I use if statements? Check to see if something is blank and throw the exception if necessary?
Calling the setters within the constructors generally has the advantage that sometimes setters already have some validation logic inside (like the setTitle in your example) and you don't want to duplicate this logic. However calling setters can lead to the problem, as you already mentioned, that subclasses may override them with unexpected behaviour. To solve this you can either make the setters private or final so that they can't get overriden. Calling only private/final setters is a good practice and should not lead to any problems.
It is fine that a constructor getting invalid data throws an exception. You do not want to create an invalid object.
It is rather bad practice to first create an empty object (through empty constructor) and then fill its data via setters. This way you will have for some time an object in a meaningless state which has some data filled, some data unfilled, and this might lead to troubles. Also, as another answer already mentioned you should think about reducing the numbers of constructors - is a Course without professor really valid? If not there doesn't need to be a constructor creating such an object...
Since this is homework, or some study, your professor prolly wanna show you things.
however ,
Course createCourse = new Course("1234","Programming 1","Pam Halpert");
is the best thing to do actually.
Depending on what you are developing, most of the time, you want to provide as little constructors as possible, unless you are designing a programming language. if you are working on a public API, or product, you should make sure that your consumers do not make mistakes, or abuse your API, if you allow them to create bugs.
Constructor can throw and exception, which is good.
As far as i see, calling the setter reason was doing some validation or some logic. which is fine.
Keep in mind, doing any work in constructor is considered a bad practice.
you should do it outside the class and pass them in as constructor arguments, or setter/getter.
Calling setters is useful if your setters do some form of data validation. This allows you to place the validation in a single place and ensure that properties that are set at the point of instantiation comply with validation rules.
However, the problem with this is that subclasses could override these setters, meaning that your expected validation no longer occurs.
As such, it makes sense to create private setters that do the validation. Call these private setters in your constructors. If you want to have public setters as well, that's fine, just create a public wrapper setter around your private setter.
Side Note:
Your professor's example is a little off.
The validation seems designed to ensure that title and code are always set. However, the code also provides constructors that allow you to not set a title. This is almost certainly a bug (I would certainly flag it as one in a code review).
Personally I am not a huge fan of setters. I like immutability so in your example I would pass in the parameters to the ctor. Do the checking there and then assign to final fields. Setters would not exist. You would only have getters.
If you want to update then you can introduce copy constructors.
Then you would know that the object when it is constructed is in a state that is valid. If some parts of it are null then you can overload the constructor. You do not know which fields need to be populated by having no-arg constrcturs and setters. By enforcing it with parameters in the constructor you are forcing the object to be initialised in a valid state.
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.