Reputation: 37
As I've come to understand it, encapsulation (in Java) is the mechanism of wrapping related data and methods into objects in a way, that the data is hidden from other classes and only accessible through the methods of the current class (a.k.a. data hiding), correct me if I'm wrong.
While reading some tutorials, I see that they specify that the getter and setter methods should be public.
I get why it shouldn't be private but why not protected or default? Would the use of protected or default getter and setter methods still count as encapsulation?
Upvotes: 1
Views: 2271
Reputation: 181199
Encapsulation in Java is achieved by making a class's fields private
. Weaker encapsulation is achieved by making them protected
.
Getter and setter methods do not implement encapsulation. Rather, they provide a mechanism for certain kinds of interaction with encapsulated data. If the data were not encapsulated then getter and setter methods would not be required. As such, sure, you can provide protected or default-access getters and setters, and even private ones. Or none at all. It's all a question of what features you want your class to expose to whom.
When one makes getters and setters public it is because they provide features that are essential for use of the class, not because that level of access is a requirement for encapsulation.
Upvotes: 3
Reputation: 24567
While reading some tutorials, I see that they specify that the getter and setter methods should be public.
That is often done in tutorials because it's easier to write, while also providing "some kind of object oriented feeling", because you still have some control using getters and setters.
You could (not recommended) also use public fields and omit the setters and getters completely:
public class Foo {
public int i;
public String s;
}
But when using setters instead you can for example validate the data:
public class Foo {
public void set(int temperature) {
if(temperature < 273) throw new IllegalArgumentException();
this.temperature = temperature;
}
}
But what if you need to validate multiple values at once? Using a setter you can only always validate the current value, but you can't validate multiple setter calls together. That's one scenario where public setters are bad.
The other thing is: Object oriented programming is much about telling names: setXYZ
doesn't you tell much. For example setTemperature
might be fine for a thermostat. But that's it. Maybe you even got something more advanced: setTemperatureLevel
(values 1-5) which then sets the internal desiredTemperature
and when this value is higher than the current temperature you want to set heater
to true
.
When using simple setters, you have no control if all those steps are done in the right order, or if maybe some step was skipped. But using a setLevel
method that does all of that inside the class, there's no way to screw up for the method caller.
But of course there are places in the Java world where those public setters and getters are quite handy: In a lot of frameworks, like something for mapping database to DAOs, or DTOs for JSON de/serialization, it makes things easier. Because here it's used as a convention for reading and writing the fields of an object. Those objects are often referred to as JavaBeans.
But when it comes to your domain objects, I highly recommend to keep everything private you don't want others to access and/or manipulate.
Upvotes: 2
Reputation: 3372
Encapsulation is meant to prevent other objects from modifying the values directly.
If you make the getters and setters private, only other methods in that class will be able to call them. this may be becouse you want to validate the value, or because you want to ensure that there is support for multithreading, or some other issue.
If you make them protected, then inheiting and extending classes will be able to call them, nut no other classes, not even your main
method would be able to call the getter and setter.
If you want to expose the values only, nothing prevents you from having a protected/private setter, and a public getter, or no setter at all ( you would have to instantiate the value in another method, or in the constructor )
Upvotes: 0
Reputation: 77226
Accessors certainly can be protected. For example, an abstract base class might expose some internal state to subclasses by using a protected getter that isn't part of the API that consumers are supposed to use.
That said, getters and setters are normally used in the context of JavaBeans, where the getters and setters define the properties of the object. If they're not publicly visible, then while they do still provide encapsulation, they don't serve that particular purpose.
The tutorials you are reading are written from the perspective of the user (who is a developer) of some object. Such properties need to be public to do their job, and most property accessors are public.
Upvotes: 0