Why saying that Memento is doing its job without violates the encapsulation, while I can implement the simple way but also without violate the encapsulation? What is the use of Memento?
I have a sample program, which will save the student details while user press the save button, and undo the action when user press then undo button.
Sample code below is implementation without using Memento pattern:
Student.java
public class Student
{
private String name;
private String gender;
private int age;
private Contact contact;
public Student(String name, String gender, int age, Contact contact)
{
this.name = name;
this.gender = gender;
this.age = age;
this.contact = contact;
}
//getter and setter
}
Main.java
public class Main extends javax.swing.JFrame implements DocumentListener
{
private Student sCopy, student;
private void btnUndoActionPerformed(java.awt.event.ActionEvent evt)
{
txtName.setText(sCopy.getName());
txtGender.setText(sCopy.getGender());
txtAge.setText(sCopy.getAge() + "");
txtPhone.setText(sCopy.getContact().getPhoneNo());
txtEmail.setText(sCopy.getContact().getEmail());
txtAddress.setText(sCopy.getContact().getAddress());
student = sCopy;
}
private void btnSaveActionPerformed(java.awt.event.ActionEvent evt)
{
sCopy = student;
Contact c = new Contact(txtPhone.getText(), txtEmail.getText(), txtAddress.getText());
student = new Student(txtName.getText(), txtGender.getText(), Integer.parseInt(txtAge.getText()), c);
}
Sample code above works perfectly, but why we need memento while it can be done so easily? I don't see where the implementation above violets the encapsulation...
Summary
Does approach above violates the encapsulation? If not, then what is the purpose of Memento? allow multiple undo? Although implementation above does not allow multiple undo, but that also can be done without applying memento.
In your approach the instance referenced by sCopy exposes all the available setters. If they are used to change values, the undo will not work correctly. This violates encapsulation, since the correctness of the undo depends on the client of your class.
A memento object would not expose any (mutating) methods, and would always be safe to use for exactly restoring the object's state.
Does approach above violates the encapsulation?
Probably. We will see.
First of all, pick some definition of what violates the encapsulation:
Having getters and setters does not in itself break encapsulation.
What does break encapsulation is having a getter and a setter for
every data member (every field, in java lingo). That is one step away
from making all data members public.
Is it your case? You have some getters and setters in the Student, maybe exposing some methods that are not necessary in your application, like gender or name. Even they are necessary, in the future can appear new fields in Student and your solution can't work anymore without violating the encapsulation.
Allow multiple undo?
It's one of the advantages.
Although implementation above does not allow multiple undo, but that also can be done without applying memento.
Yes, but maybe violating the encapsulation.
Related
We always say that, Encapsulation keeps data and functionality safe from the outside world.
So its a protective wrapper around the class and the code can be saved from unauthorized access by outer world.
But what if,
I declare one variable with public modifier will it break Encapsulation ?
Encapsulation in Java is a mechanism of wrapping the data (variables) and code acting on the data (methods) together as a single unit. In encapsulation, the variables of a class will be hidden from other classes, and can be accessed only through the methods of their current class. Therefore, it is also known as data hiding.
public class EncapTest {
private String name;
private String idNum;
private int age;
public int getAge() {
return age;
}
public String getName() {
return name;
}
public String getIdNum() {
return idNum;
}
public void setAge( int newAge) {
age = newAge;
}
public void setName(String newName) {
name = newName;
}
public void setIdNum( String newId) {
idNum = newId;
}
}
so that all your methods and variable should be private
In my idea modifiers absolutely supports Encapsulation. Maybe you just violate Information Hiding.
Encapsulation is not information hiding. Information hiding is a more fundamental technique than encapsulation. We should clarify between Encapsulation and Information Hiding. (see the reference)
Encapsulation is a technique for expressing the boundaries of
those modules.
Suppose that we have an attribute in our class and we need to set some values from external the class. We can not define it as public. We can not define it as protected too (see this question), the only way to define this types of conditions is defining some methods (or some modifiers in very simple interface). In this case we Encapsulate it.
So what is the difference between a public attribute and a private attribute with modifiers?
In a very big projects, we can add some other conditions to modifiers without any changes to other parts of project (the OCP of SOLID).
Finally: In some cases we need to set some values from outside the class to attributes. So sometimes we need to use modifiers and it is the encapsulation way to access the fields. We can not define the fields as public or protected in OOP.
First of all, let's see what encapsulation really is.
Encapsulation is one of the four OOP concepts.
In encapsulation, the variables of a class will be hidden from other classes, and can be accessed only through the methods of their current class. Therefore, it is also known as data hiding.
So making a class variable public it's not encapsulation anymore.
Let's see some real usages of encapsulation:
By encapsulating, you force yourself and other developers to access that variable through their getters and setters. Let's be honest, it's the same thing as if the field was public, right?
But what if you add some logic to the setters?
public class User {
private String username;
private String password;
// username getter and setter not displayed in this example.
public void setPassword(String password) {
this.password = someCoolHashingMethod(password);
}
public String getPassword() {
return this.password;
}
}
Do you see what's happening there? You force the password to be stored as a hash instead of clear. (There are many ways to protect a password but we'll stick to this dummy example for now).
Another real use for encapsulation is that you can change the name of the variable without changing the code everywhere in your application.
So you if you change it's name and it's not encapsulated, you will have to go everywhere you used it, modified it, to change there aswell. So a project level refactorization is needed. But if it's encapsulated, you used getters and setters everywhere! That means you just need to change it there only. Example:
public class User {
private String username;
private String pass; // <---- notice the new name
// username getter and setter not displayed in this example.
public void setPassword(String password) {
this.pass = someCoolHashingMethod(password); // <---- notice the new name
}
public String getPassword() {
return this.pass; // <---- notice the new name
}
}
Hope this answered a little bit more than your question really was.
I was reading this answer on SESE about encapsulation and getters/setters. Suppose I favor the use of immutable classes, so if a setter were implemented, it would return the a new object reflecting the change, for example:
//return a new Book reflecting the price change.
public Book updatePrice(double price){}
In the link, the answer suggested I have a method called getDisplayinformation() that returns a data structure.
(think an array indexed by an enum, a struct, or a methodless class)
Following this advice how would I return a Book with a List of authors?
public final class Author{
private final String id;
private final String firstname;
private final String lastname;
//Constructor
}
public final class Book{
private String bookID;
private final String title;
private List<Author> authorsList;
private double price;
//Constructor
}
Suppose I wanted to return a Map<String,String>.
public Map<String,String> getDisplayinformation(){
Map<String,String> displayMap = new HashMap<String,String>();
display.put("BookTitle", title);
display.put("ID", bookID);
display.put("Price", price.toString())
//insert authorsList;
return displayMap;
}
The answer you quote got half of it right. Providing getters for fields does break encapsulation, because it makes the caller dependent on some internal structure.
Now, returning a map where the caller needs to know the keys and knows what that information is, is basically not different than providing a getter for that field.
Object-orientation tries to tell us that the functionality needs to be bundled with the data. So, the Book has to have some method to present the Book. I would not call it getDisplayInformation(), rather simply display(). It can return something, and it can take relevant parameters too.
The point is, that anything returned by display() must be about the presentation, and must not be about the book. Semantics about being a book should be lost at that point, otherwise the caller will be tightly coupled.
So, it's ok to return an XML document, JSON document, HTML, a Wicket Component, whatever it is you can use for presentation that is independent of the Book.
Or, the method could take an argument to present itself to. Like AWT Component.paint(Graphics g) or something.
Note: this is actually a controversial subject. Mixed-paradigm development (a mix of procedural and ood) would argue that presentation needs to be separated from objects, while object-orientation argues that data and function belong always together.
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.
I have few issues/doubts to fill values in a HashMap
I want a HashMap to accept "Student" as key and "Details" as value.
Since key to a hashMap should be immutable I have some doubts how can this be dealt if
Student class did not cloneable
Student class has reference to which in turn have reference to "Lab"
public class Student {
private String id;
private String name;
private Department dept;
public Student(String id, String name, Department dept)
{
this.id=id;
this.name=name;
this.dept=dept;
}
public Department getDepartment()
{
return this.dept;
}
}
public class Department {
private String deptId;
private Lab lab;
public Department(String deptId, Lab lab)
{
this.deptId=deptId;
this.lab=lab;
}
public void setLab(Lab lab)
{
this.lab=lab;
}
}
public class Lab {
private String labId;
private String labName;
public Lab(String labId, String labName)
{
this.labId=labId;
this.labName=labName;
}
}
public class StudentDetails
{
private String fatherName;
private String address
public StudentDetails(String fatherName, String address)
{
this.fatherName=fatherName;
this.address=address;
}
}
public class StudentMaintainer {
public static void main(String[] args)
{
StudentDetails stDetails= new StudentDetails("John","Mumbai");
Lab lab= new Lab("100","CS");
Department dept= new Department("900", lab);
Student st = new Student("3000",dept);
Map<Student,StudentDetails> studentMaintainer= new ArrayList<>();
studentMaintainer.put(st,stDetails);
}
}
Now Even if Student is cloneable, I can get reference of Department and call setLab() which changes the StudentObject. (Am I wrong?)
Now if Department and Lab are from 3rd party jars, how can I use Student Object in my Map if Student hashCode is (primeNumber+Student.id+Department.id+Lab.id).hashcode() [just some weird case];
Immutability has nothing to do with Cloneable as far as I understand it, and in fact just the opposite. Immutability has more to do with declaring the class final and using immutable fields, non-overridable methods, no setter methods, getter methods that return deep copies of fields or immutable fields, etc... Please read A Strategy for Defining Immutable Objects for more on this.
Also your code has a pseudo-constructor:
public void Student(String id, String name, Department dept)
{
this.id=id;
this.name=name;
this.dept=dept;
}
A true constructor should not be declared to return anything, not even void. Better would be:
// note the difference?
public Student(String id, String name, Department dept)
{
this.id=id;
this.name=name;
this.dept=dept;
}
Also, your Student class should properly override equals and hashCode if it is to work well as a key for a HashMap.
Now Even if Student is cloneable, I can get reference of Department
and call setLab() which changes the StudentObject. (Am I wrong?)
You are correct. This can happen, and can cause your Student class to appear to be mutated. For an instance of Student to be immutable, you must not be able to modify any of its fields[0]. That includes calling something like a setter method on one of its fields.
Now if Department and Lab are from 3rd party jars, how can I use
Student Object in my Map if Student hashCode is
(primeNumber+Student.id+Department.id+Lab.id).hashcode() [just some
weird case];
That is a very good question. You obviously can't just change the classes to be immutable, since you don't have control over them, so you may have to get a bit creative. Possible solutions:
if the third party objects you want to use are interfaces, you could implement the interface with your own type, where the body of every mutator method throws an exception (think e.g. java.util.Collections.unmodfiableList). This has the benefits that you can still refer to the third party class in your codebase, but the drawback that calling mutator methods will fail at runtime, rather than at compile time.
write adapters in your own codebase, like this:
public final class MyImmutableDepartment {
private final MyImmutableLab lab;
private final String departmentId;
public MyImmutableDepartment(Department thirdPartyMutableDepartment) {
this.departmentId = thirdPartyMutableDepartment.getId();
this.lab = new MyImmutableLab(thirdPartyMutableDepartment.getLab());
}
// getters and the MyImmutableLab class left as an exercise
}
This has the advantage that you know at compile time, the classes cannot be mutated.
The downside in both approaches is that you basically have to mirror every class from the third party library, to ensure they're immutable.
I don't think there's any other alternatives.
[0] there are some cases where this is possible, and can be used for internal caching, but it's a decent guideline to stick to when learning.
Student does not need to be immutable! Specifically, the requirement is that the behavior of equals/hashCode doesn't change when the key is in the HashMap.
This can be accomplished in three ways:
Don't implement equals/hashCode. If you use the default reference equality, it doesn't matter how you mutate the key. To clarify intent, override those methods, explicitly call super.equals, and make them final.
Don't include any fields that will mutate in your calculation of equals/hashCode. Or, if the properties of a field may change but not the reference, use reference equality (==) instead of field.equals() and call System.identityHashCode(field) instead of field.hashCode()
Don't mutate the object while it is used as a key in the HashMap. A bit dangerous, but works fine if references aren't held by code beyond your control. Document the requirement.
But, in your concrete example, each student has an id. Why would you use any other properties when implementing equals/hashCode.?
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.