Explain encapsulation in OOP - java

I am new to OOP and I have some doubts regarding encapsulation.
What is mean by difference between "partial" and "weak" encapsulation? An example in java will help me.
Does encapsulation means only place data in capsule like a class, or does an access modifier have to be there?
I read that encapsulation means to hide and club together data.
In this example:
class A{
public int a;
public void foo(){}
}
Is above code is example of encapsulation? If yes, then there is nothing hidden from outer world as a and foo are public. Must a and foo be private for this example to be considered encapsulation?

Here is a good explanation https://mail.mozilla.org/pipermail/es-discuss/2010-December/012334.html
Basically if you were implementing a java library or API you would aim for strong encapsulation, so that users couldn't access things they aren't supposed to.
Strong encapsulation means that no one can access secret internal variables because you have a proper inheritance heirachy and all that stuff is hidden.
Your example is very weak encapsulation because the variable a is public. If your class was an API and a was actually credit_card_details you would be in big trouble.
For starters you would set those variables as private and use getters and setters to access them.
Overall though, you need something abstracted in order to encapsulate it. The only other thing I have heard encapsulation refer to from an OOP perspective is simply bundling real world objects into classes

Object orientation is about messages. If you can only ask for setting or getting a value inside an object, then the values are encapsulated. The only way to access them is via the predefined protocol, which is the setter or the getter or whatever other methods.
If you have a public field, it looks like there's no encapsulation, but you still don't own the variable, think of it as a default set or get.

Related

Can we say a class with all public member variables and all public methods as encapsulated class?

By definition, encapsulation in Java is a process of wrapping code and data together into a single unit. But if a class has 2 member variables and a method and both the variables and method has public access modifier, can we say that class as encapsulated class?
For example, can we say below class is encapsulated or not
public class AddNumbers {
public int a;
public int b;
public void add(){
System.out.println(a+b);
}
}
Yes, or no. Depending on how one defines "encapsulation".
Given the phrasing of your question, I assume you are working with the definition of encapsulation from Wikipedia, which (as of now) reads
In object-oriented programming (OOP), encapsulation refers to the bundling of data with the methods that operate on those data, or the restricting of direct access to some of an object's components.
I disagree with this definition. Or more precisely, I think it unnecessarily distinguishes "encapsulation" and "data hiding" which is not in line with how I see the term "encapsulation" used in day-to-day conversations. In fact even the Wikipedia talk page mentions this problem of the definition (with no apparent counter-voices).
So if you follow that Wikipedia definition, then yes, your code uses encapsulation ("an encapsulated class" is not a phrase I've ever heard anyone use this way, I'd avoid it).
If you follow the school of thought that information hiding and encapsulation are synonymous (or at least very tightly bound together) then your code is not using encapsulation.
See this paragraph from the Wikipedia article on Information Hiding:
The term encapsulation is often used interchangeably with information hiding. Not all agree on the distinctions between the two, though; one may think of information hiding as being the principle and encapsulation being the technique.
The meaning of Encapsulation, is to make sure that "sensitive" data is hidden from users
to make your class encapsulated you need
Declare class variables/attributes as private
provide public get and set methods to access and update the value of a private variable
your class has public data, that is, it is not protected (encapsulated) and therefore can be accessed and modified by everyone
I recommend this reading for a better understanding of encapsulation
java_encapsulation

Treatment to field inside the class. Through getter or explicit?

consider the class:
class MyClass{
MyOtherClass obj;
//setObj and getObj methods
public void someMethod(){
...
//access to obj needs.
...
}
}
How to right replace
//access to obj needs.
through getter or explicitly?
P.S.
I saw both variants in my expirience.
Personally I would say it depends on the level of "connection" between both classes. If they are in the same package and part of the same "mecanism" (one would have no reason to exist without the other), bypassing accessors is acceptable.
So here we're talking about code in Class MyClass accessing information in an instance of MyOtherClass.
Typically you don't get a choice. If MyOtherClass exposes a getter for a data member, it's unlikely to also expose that data member. If it does (even if the data member is, say, protected but the accessor is public), the design is a bit questionable.
But if you do have the choice, I would use the getter, rather than the exposed data member. It's a bit subjective, but using data members rather than accessors more tightly binds the classes together. In my protected/public example, you'd have more work to do if for any reason you wanted to move MyClass to a different package.
It's worth noting that using the getter is not more expensive in performance terms with a decent JVM (such as the one from Sun). If the code becomes a performance "hotspot" for whatever reason (or possibly even if it doesn't), the JVM's JIT will convert the call to the getter into a direct access anyway (presuming it's a pure getter), so you get the benefit of abstraction at the coding/design-time without the function call overhead at runtime.
To answer this, let's first see why getters and setters were introduced in the first place. It is clear that direct access to data members is simpler.
SOme of the reasons are:
for a better encapsulation, to hide the property implementation from a class user. For example you can internally store a temperature value in C and return it by a getter in F.
for more control over the access. If you want to do something more besides pure getting/setting a piece of data, you would need a method. For example, you might want to log the change of value for audit purpose
methods are much more "interface friendly" than pure data members.
In this case the class itself accesses its own property. Are you sure you want that?
If so, let's see the reasons:
Encapsulation is definitelly not needed, since the class itself accesses its own attributes.
Do you need to somehow control access here? Do you need to do something else, besides get/set? Are there any other possible users of this class?
If all these answers are NO, ans especially if the only user of this class the mentioned method, then go for a simpler option and use direct access, without getters/setters.
If some of the answers is true, just make a simple trade-off and decide.

What is the point of getters and setters? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why use getters and setters?
I have read books on Java, saying that it is good to create setters and getters for variables such as x and y. For example:
public int getX(){
return x;
}
public void setX(int x){
this.x = x;
}
But what is the difference from that and
...(shape.x)... // Basically getX()
and
shape.x = 90; // Basically setX()
If setters and getters are better, what practical problems would arise?
Multiple reasons:
If you allow field access like
shape.x = 90
then you cannot add any logic in future to validate the data.
say if x cannot be less than 100 you cannot do it, however if you had setters like
public void setShapeValue(int shapeValue){
if(shapeValue < 100){
//do something here like throw exception.
}
}
You cannot add something like copy on write logic (see CopyOnWriteArrayList)
Another reason is for accessing fields outside your class you will have to mark them public, protected or default, and thus you loose control. When data is very much internal to the class breaking Encapsulation and in general OOPS methodology.
Though for constants like
public final String SOMETHING = "SOMETHING";
you will allow field access as they cannot be changed, for instance variable you will place them with getters, setters.
Another scenario is when you want your Class to be immutable, if you allow field access then you are breaking the immutability of your class since values can be changed. But if you carefully design your class with getters and no setters you keep the immutability intact.
Though in such cases you have to be careful in getter method to ensure you don't give out reference of objects(in case your class have object as instances).
We can use the private variables in any package using getters and setters.
Using getter and setter functions allow for constraints and encapsulation. Lets say x is the radius. shape.x = -10 would not make much sense. Also, if someone tries to set an illegal value, you can print an error, set a default value, or do nothing.
It is good practice to make member variables private so they cannot be modified directly by programs using them.
Mutator functions
Encapsulation
A lot of people have mentioned encapsulating the specifics of the implementation, which to me is the biggest reason to use getters and setters in a class. With this, you also get a lot of other benefits, including the ability to throw out and replace the implementation on a whim without needing to touch every piece of code that uses your class. In a small project, that's not a big benefit, but if your code ends up as a well-used (internal or public) library, it can be a huge benefit.
One specific example: complex numbers in mathematics. Some languages have them as a language or framework feature, others don't. I will use a mutable class as an example here, but it could just as easily be immutable.
A complex number can be written on the form a + bi with real and imaginary parts, lending itself well to [gs]etRealPart and [gs]etImaginaryPart.
However, in some cases it's easier to reason about complex numbers on polar form re^(iθ), giving [gs]etRadius (r) and [gs]etAngle (θ).
You can also expose methods like [gs]etComplexNumber(realPart, imaginaryPart) and [gs]etComplexNumber(radius, angle). Depending on the argument types these may or may not need different names, but then the class' consumer can use either as fits its needs.
The two forms are interchangeable; you can fairly easily convert from one to the other, so which form the class uses for internal storage is irrelevant to consumers of that class. However, consumers may use either form. If you choose the form a+bi for internal representation, and expose that using fields rather than getters and setters, not only do you force the class consumers to use that form, you also cannot later easily change your mind and replace the internal representation with re^(iθ) because that turns out to be easier to implement in your particular scenario. You're stuck with the public API you have defined, which mandates that specifically the real and imaginary parts are exposed using specific field names.
One of the best reasons I can think of for getters and setters is the permanence of a class's API. In languages like python you can access members by their name and switch them to methods later. Because functions behave differently than members in java once you access a property thats it. Restricting its scope later breaks the client.
By providing getters and setters a programmer has the flexibility to modify members and behavior freely as long as the adhere to the contract described by the public API.
Another good reason to user getter and setter can be understand by the following example
public class TestGetterSetter{
private String name ;
public void setName(String name){
this.name = name ;
}
public String getName(){
return this.name ;
}
}
The point of getters and setters is that only they are meant to be used to access the private variable, which they are getting or setting. This way you provide encapsulation and it will be much easier to refactor or modify your code later.
Imagine you use name instead of its getter. Then if you want to add something like a default (say the default name is 'Guest' if it wasn't set before), then you'll have to modify both the getter and the sayName function.
public class TestGetterSetter{
private String name ;
public void setName(String name){
this.name = name ;
}
public String getName(){
if (this.name == null ){
setName("Guest");
}
return this.name ;
}
}
There is no requirement for getters and setter to start with get and set - they are just normal member functions. However it's a convention to do that. (especially if you use Java Beans)
Let's say, hypothetically, you find a library that does a better job of what you have been doing in your own class (YourClass). The natural thing to do at this point is to make YourClass a wrapper interface to that library. It still has a concept of "X" which your client code needs to get or set. Naturally, at this point you pretty much have to write the accessor functions.
If you neglected to use accessor functions and let your client code access YourClass.x directly, you would now have to rewrite all of your client code that ever touched YourClass.x. But if you were using YourClass.getX() and YourClass.setX() from the beginning, you will only need to rewrite YourClass.
One of the key concepts of programming, and especially object oriented programming, is hiding implementation details so that they're not used directly by code in other classes or modules. This way, if you ever change the implementation details (as in the example above), the client code doesn't know the difference and doesn't have to be modified. For all your client code knows, "x" might be a variable, or it might be a value that is calculated on the fly.
This is an oversimplification and doesn't cover all the scenarios where hiding implementation is beneficial, but it is the most obvious example. The concept of hiding implementation details is pretty strongly tied to OOP now, but you can find discussions of it going back decades before OOP was dreamed up. It goes back to one of the core concepts of software development, which is to take a big nebulous problem, and divide it into small well-defined problems which can be solved easily. Accessor functions help keep your small sub-tasks separate and well-defined: The less your classes know about each other's internals, the better.
There are lots of reasons. Here are just a few.
Accessors, getters in particular, often appear in interfaces. You can't stipulate a member variable in an interface.
Once you expose this member variable, you can't change your mind about how it's implemented. For example, if you see a need later to switch to a pattern like aggregation, where you want the "x" property to actually come from some nested object, you end up having to copy that value and try to keep it in sync. Not good.
Most of the time you are much better off not exposing the setter. You can't do that with public fields like x.
Before get into the answer, we gotta know something prior...! "JavaBeans".
JavaBeans are java classes that have properties. For our purpose, think of properties as private instance variables. since they're private, the only way they can be accessed
from outside of their class is through 'methods'in the class.
The methods that change a propertiy's value are called setter methods, and the methods that retrieve a property's value are called getter methods.
I would say that neither the getters/setters nor the public members are good Object Oriented design. They both break OOP Encapsulation by exposing an objects data to the world that probably shouldn't be accessing the properties of the object in the first place.
This is done by applying the encapsulation principle of OOP.
A language mechanism for restricting access to some of the object's components.
This means, you must define the visibility for the attributes and methods of your classes. There are 3 common visibilities:
Private: Only the class can see and use the attributes/methods.
Protected: Only the class and its children can see and use the attributes/methods.
Public: Every class can see and use the attributes/methods.
When you declare private/protected attributes, you are encouraged to create methods to obtain the value (get) and change the value (set). One example about visibility is the [ArrayList][2] class: it has a size property to know the actual size of the inner array. Only the class must change its value, so the code is something like
public class ArrayList<E> {
private int size;
private Object[] array;
public getSize() {
return this.size;
}
public void add(E element) {
//logic to add the element in the array...
this.size++;
}
}
In this example, you can see that the size value can change only inside the class methods, and you can get the actual size by calling it in your code (not mutating it):
public void someMethod() {
List<String> ls = new ArrayList<String>();
//adding values
ls.add("Hello");
ls.add("World");
for(int i = 0; i < ls.size(); i++) {
System.out.println(ls.get(i));
}
}
Getters and setters encapsulate the fields of a class by making them accessible only through its public methods and keep the values themselves private. That is considered a good OO principle.
Granted, it often seems like redundant code if it does nothing more than setting or returning a value. However, setters also allow you to do input validation or cleanup. Having that in one place improves data integrity for your objects,
Because we are using Object oriented programming language.
Here we are using Data hiding and encapsulation.
The variable should not directly accessible from out side world (for achiving data hiding) so we will create it private so
shape.x
is not correct.
Getter and setter method are used to get and set the value of x which is the way to achive encapsulation.

Does Java follow Object Oriented Programming Model fully?

The following code illustrates the situation:
class Human {
private String heart = "default heart";
public void control(Human h) {
h.heart = "$%^&*##!#^";
}
public String getHeart() {
return heart;
}
}
public class HumanTest {
public static void main(String[] args) {
Human deb = new Human();
Human kate = new Human();
System.out.println(deb.getHeart());
kate.control(deb);
System.out.println(deb.getHeart());
}
}
Here heart [private variable] of deb got modified unfortunately. :)
Java allows the code to run without any error.But is it justified to give a object the privilege to access private member of other object even if the code is in the same class ?
Shouldn't Java disallow this?
As I know, private means restricting access beyond the class source code. But the same concept is applied in the source code above. and the result is disastrous since a person's heart can't be modified by any random person .
If the result is disastrous, you shouldn't code the class so that it allows it. The "bug" is not caused by code external to the class, but by code of the class itself. So it's simply a bug in your code.
If Java did not allow it, you could only compare objects of the same class by their public attributes, for example, which would either break encapsulation (by exposing private stuff), and/or be very slow (by forcing to make defensive copies of the private attributes to make them available to other objects.
Some languages have encapsulation at the object level, others (Java, C++) at the class level. It sounds like you're used to (or have just read about) encapsulation at the object level. Frankly, I find the class level much more natural, but perhaps that's just because C++ provided my introduction to programming with classes. Class-level encapsulation makes some idioms (factory methods, copy constructors, comparison operators) much easier to write. With object-level encapsulation, you end up exposing more than you really want to just to be able to implement these features.
In any case, neither way is "correct" -- they're just different.
Look into defensive copy to avoid this situation. It is because java objects operate more like references. The 'pointer' doesn't change, but once you know it you can change the value it contains.
http://www.informit.com/articles/article.aspx?p=31551&seqNum=2
This isn't breaking object orientation - it's about encapsulation of elements internal to a class.
It may seem silly that you can do this with this example but it's actually not a bad thing at all as far as I see it. The point of encapsulating elements of a class is so that other classes can't modify them - they can only see the public interface of class Human for instance to make changes. This means more than one person can work on the same project, writing different classes (or you can work on the same project at different times writing different classes) and they don't need to know the inner workings of the code.
However, the only place (bar reflection) you can access a private field directly in Human is from Human. When you're writing the Human class, if you choose to make modifications to private fields of other Human objects, that's up to you - but it's all contained within that one class, which is your design. If you do this in a way that's not appropriate, then it's a flaw in your design and not with Java - there's some cases where it makes perfect sense to do this!
Well, the way I see it and this is just my interpretation of the private keyword, a private is private to the class and can be accessed inside the class. It is not restricted to instances of the class. Therefore you can't do kate.heart="xpto" in the "humantest" class because that would try to breach it's privacy, but using kate's code to alter deb's heart is allowed because it is being handled inside the class.
Java language strictly following the Object oriented concept. Here also that's correct..ritght? Using the object of your class you are modifying your class's variables. But its upto the programmer who can have control over his objects.
Human's heart is private inside Human's class. But using the control method you are giving access to it from outside. That's why it gets modified..What's the problem in that.?

Is it bad to have public variables in a non-static class?

I am writing a game and I have a class for the input which contains booleans for all the different keys. I create an instance of this class in the main game class. Is it ok for the booleans to be public, or should I access them with accessors?
Instead of having a boolean for each key, it would be more readable and easier to code if you had a private Map<String, Boolean> keyStates, with all keys initialized to false. Then your accessors might be:
public void setPressed(String keyName) {
keyStates.put(keyName, true);
}
public void setReleased(String keyName) {
keyStates.put(keyName, false);
}
public boolean isPressed(String keyName) {
return keyStates.get(keyName);
}
The general reason for having accessor methods rather than public variables is that it allows the class to change its implementation without requiring changes in the classes that interact with its members. For example, with the above, you can now add code to count or log key presses, or change the underlying type of Map used, without exposing any of this to the outside.
This is not personal preference. Encapsulation and Interfaces are integral parts of OO Software Engineering, and are the primary design reasons that the Internet is possible from a technical POV.
Generally I would recommend using getters and setters as it is cleaner, more organized, and more readable. This will also help if you have a lot of different programmers looking at your code. My outlook is to always make your variables private unless you need to expose them for a specific reason. If performance is really an issue in your game then making your variables public will help a little by reducing function calls.
It's mainly a personal taste thing - I'm sure you'll find people arguing on both sides, and I'd say it's not black or white but depends on how "big" the class is.
The rationale for using getters and setters is so that you abstract out the actual representation as a field, in order to give you the freedom to start presenting this as e.g. a derived value without changing your interface. So really it comes down to how valuable the interface to this class is to you.
If it's part of your first-class public interface, then definitely use getters and setters. At the other extreme, if it's a simple data holder like a tuple that's used solely within a single class (e.g. to map database rows before transformation into another class), then I wouldn't hesitate to use fields; there's no real value to the interface as it's only being used internally.
So how many classes/packages would use this class? If it's a private, "local" class then I don't think there's anything wrong with just using the fields, and updating your callers if this ever needs to change.
Accessing fields is much easier to justify if they're final too, which is often the case with this sort of object.
It's not bad, but usually you'll want to encapsulate the state of an object.
Standard practice is to make member variables either protected or private with getters/setters that follow java bean convention. This tends to be somewhat verbose, but there is a very nice library (www.projectlombok.org) out there that generates the getters/setters/constructors/toString/hashCode/equals methods for you.
It is always a good java programming practice to declare the class variables as private and access them with public getter and setter methods unless its really needed to declare them as public .
If you are using an IDE , then its just a click away to generate getters and setters for class variables/member variables .
And now that you have been told over and over to use getter and setters, and because you are in Java (where IDEs help you make getters/setters trivially, and everyone clearly uses them), read over this thread to help add some balance to your usage of them:
Getters and Setters are bad OO design?

Categories