class Person
{
private BankAccount account;
Person(BankAccount account)
{
this.account = account;
}
public Person someMethod(Person person)
{
//Why accessing private field is possible?
BankAccount a = person.account;
}
}
Please forget about the design. I know that OOP specifies that private objects are private to the class. My question is, why was OOP designed such that private fields have class-level access and not object-level access?
I am also a bit curious with the answer.
The most satisfying answer that I find is from Artemix in another post here (I'm renaming the AClass with Person class):
Why have class-level access modifiers instead of object-level?
The private modifier enforces Encapsulation principle.
The idea is that 'outer world' should not make changes to Person internal processes because Person implementation may change over time (and you would have to change the whole outer world to fix the differences in implementation - which is nearly to impossible).
When instance of Person accesses internals of other Person instance - you can be sure that both instances always know the details of implementation of Person. If the logic of internal to Person processes is changed - all you have to do is change the code of Person.
EDIT:
Please vote Artemix' answer. I'm just copy-pasting it.
Good question. It seems that object level access modifier would enforce the Encapsulation principle even further.
But actually it's the other way around. Let's take an example. Suppose you want to deep copy an object in a constructor, if you cannot access the private members of that object. Then the only possible way is to add some public accessors to all of the private members. This will make your objects naked to all other parts of the system.
So encapsulation doesn't mean being closed to all of the rest of the world. It means being selective about whom you want to be open to.
See the Java Language Specification, Section 6.6.1. Determining Accessibility
It states
Otherwise, if the member or constructor is declared private, then
access is permitted if and only if it occurs within the body of the
top level class (ยง7.6) that encloses the declaration of the member or
constructor.
Click the link above for more details. So the answer is: Because James Gosling and the other authors of Java decided it to be that way.
This works because you are in the class Person - a class is allowed to poke inside it's own type of class. This really helps when you want to write a copy constructor, for example:
class A
{
private:
int x;
int y;
public:
A(int a, int b) x(a), y(b) {}
A(A a) { x = a.x; y = y.x; }
};
Or if we want to write operator+ and operator- for our big number class.
Just my 2 cents on the question of why the semantics of the private visibility in Java is class level rather than object level.
I would say that convenience seems to be the key here. In fact, a private visibility at object level would have forced to expose methods to other classes (e.g. in the same package) in the scenario illustrated by the OP.
In truth I was not able neither to concoct nor to find an example showing that the visibility at class-private level (like offered by Java) creates any issues if compared to visibility at object-private level.
That said, programming languages with a more fine-grained system of visibility policies can afford both object visibility at object level and class level.
For example Eiffel, offers selective export: you can export any class feature to any class of your choice, from {NONE} (object-private) to {ANY} (the equivalent of public, and also the default), to {PERSON} (class-private, see the OP's example), to specific groups of classes {PERSON, BANK}.
It's also interesting to remark that in Eiffel you don't need to make an attribute private and write a getter to prevent other classes from assigning to it. Public attributes in Eiffel are by default accessible in read-only mode, so you don't need a getter just to return their value.
Of course you still need a setter to set an attribute, but you can hide it by defining it as "assigner" for that attribute. This allows you, if you wish, to use the more convenient assignment operator instead of the setter invocation.
Because the private access modifier renders it visible only within the class. This method is still IN the class.
the private field is accessible in the class/object in which the field is declared. It is private to other classes/objects outside of the one it is located in.
First thing here we have to understand is all we have to do is must follow oops principles so encapsulation is say that wrap data within package(i.e. class) and than represent all data as Object and easy to access. so if we make field as non-private than
it's accessed indivisually. and it result into bad paratice.
With reflection concept in Java is possible modify fields and methods privates
Modificando metodos y campos privados con Refleccion en Java
Related
This question already has answers here:
Why are getter and setter method important in java? [duplicate]
(6 answers)
Closed 7 years ago.
Encapsulation is hiding the data. I would like to hear some really interesting answers here.
What is the point behind keeping variables as private when we already declare public setter methods for variables?
I understand the usage of encapsulation but when we are making the setters as public what is the point behind keeping the variables as private, we can directly use public access modifiers.
Is it because we do not want others to know the exact way we are storing data or managing data on the back-end?
Is it because we do not want others to know the exact way we are
storing data or managing data on the back-end?
Yes, that's the point. It is related to the concepts of abstraction and information hiding too.
You provide a public setter that when invoked by the class client will have the effect that you have documented. It is none of the client's business how this effect is actually achieved. Are you modifying one of the class attributes? Ok, let the client know that, but not the fact that you are actually modifying a variable. In the future, you could want to modify your class so that instead of a simple backup variable it uses something completely different (a dictionary of attributes? An external service? Whatever!) and the client will not break.
So your setter is an abstraction that you provide to the client for "modify this class attribute". At the same time you are hiding the fact that you are using an internal variable because the client doesn't need to know that fact.
(Note: here I'm using the word "attribute" as a generic concept, not related to any concrete programming language)
I fully agree with Konamiman's answer, but I'd like to add one thing:
There are cases where you really don't want that abstraction. And that's fine.
A simple example I like to use here is a class for a 3-dimensional float vector:
class Vector3f {
public:
float x;
float y;
float z;
};
Could you make those fields private and provide setters instead? Sure, you could. But here you might argue that the class is really just supposed to provide a tuple of floats and you don't want any additional functionality. Thus adding setters would only complicate the class and you'd rather leave the fields public.
Now, you can easily construct scenarios where that might bite you later on. For instance, you might one day get a requirement that Vector3fs are not allowed to store NaNs and should throw an exception if anyone tries to do so. But such a hypothetical future problem should not be enough to justify introducing additional abstractions.
It's your call as a programmer to decide which abstractions make sense for the problem at hand and which ones would only get in your way of getting the job done. Unnecessary abstractions are over-engineering and will hurt your productivity just as much as not abstracting enough.
Bottom line: Don't blindly use setters everywhere just because someone claimed that's good practice. Instead, think about the problem at hand and consider the tradeoffs.
Because by encapsulation we provide single point of access. Suppose you define a variable and its setter as follows
String username;
public void setUsername(String username){
this.username = username;
}
Later you like to add some validation before setting username property. If you are setting the username at 10 places by directly accessing the property then you don't have single point of access and you need to make this change at 10 places. But if you have one setter method then by making a change at one place you can easily achieve the result.
Think about this : I'm representing a real life object, a Lion through a class. I'd do something like this.
class Lion {
public int legs;
}
Now my class is needed by some other developer to create an object and set its legs field. He'd do something like this
Lion jungleKing = new Lion();
jungleKing.legs = 15;
Now the question is, Java won't restrict him to setting any number more than 4 as the number of legs for that object. It's not an error, and it'll run just fine. But it's a logical blunder, and the compiler won't help you there. This way a Lion may have any number of legs.
But if we write the code this way
class Lion {
private int legs;
public void setLegs(int legs){
if(legs > 4){
this.legs = 4;
}
else this.legs = legs;
}
}
Now you won't have any Lion with more than 4 legs because the policy of updating the fields of the class has been defined by the class itself and there's no way anyone not knowing the policy is going to update the legs field because the only way to update the legs field is through the setLegs() method and that method knows the policy of the class.
Although Konamiman's answer is spot on, I'd like to add that, in the particular case of public setters versus directly exposing public fields you are asking, there is another very important distinction to keep in mind apart from information hiding and decoupling implementation from the public surface, or API, of a class; validation.
In a public field scenario, there is no way to validate the field's value when it's modified. In case of a public setter (be it a Foo {get; set;} property or a SetFoo(Foo value)) method you have the possibility to add validation code and launch required side-effects and this way ensure that your class is always in a valid or predictable state.
What if you do want to a range check before assignment? That's one of the cases I use setters and getters
More or less simple and realistic example I encountered in practice is an Options class, which has a lot of setters and getters. At some point you might want to add new option which depends on others or has side effects. Or even replace group of options with Enum. In this case setA function will not just modify a field, but will hide some additional configuration logic. Similarly getA will not just return value of a, but something like config == cStuffSupportingA.
Wikipedia has a good overview of [mutator methods(https://en.wikipedia.org/wiki/Mutator_method), which is what setter methods are and how they work in different languages.
The short version: if you want to introduce validation or other logic that gets executed on object modification it is nice to have a setter to put that logic in. Also you may want to hide how you store things. So, those are reasons for having getters/setters. Similarly, for getters, you might have logic that provides default values or values that are dependent on e.g. configuration for things like Locale, character encoding, etc. There are lots of valid reasons to want to have logic other than getting or setting the instance variable.
Obviously, if you have getters and setteres, you don't want people bypassing them by manipulating the object state directly, which is why you should keep instance variables private.
Other things to consider include whether you actually want your objects to be mutable at all (if not, make fields final), whether you want to make modifying the object state threadsafe with e.g. locks, synchronized, etc.
Setting fields as private documents a powerful fact: these private fields are only directly used within the current class. This helps maintainers by not having to track down field usage. They can reason better on the code by looking at the class and determining that the effects on and from these fields with the class' environment go through public and protected method calls. It limits the exposure surface on the class.
In turn, defining a "setter" for a private field is not about giving it publicity again. It is about declaring another powerful fact: an object belonging to this class has a property that can be modified from the outside. (The terms object and property are used in the sense of a bounded part of the whole and an observable fact about this part, not in the OOP sense)
Why then declare a "setter" on a field when making the field public would suffice? Because declaring a field not only binds a name to a property of the objects of the class, but also commits to use memory storage for this property.
Therefore, if you declare a "private field with a setter", you declare three things:
You declare that the name you gave to the field/setter cluster represents a property of the object which is of interest when the object is seen as a black box.
You declare that the value of this property is modifiable by the environment of the object.
You declare that in this particular concrete class, the property of the object is realized by committing some memory storage to it.
I advocate that you never make your fields private with getters and setters indiscriminately. Fields are for describing storage. Methods are for interactions with the environment. (And the particular case of "getters" and "setters" are for describing properties of interest)
Everyone knows that Java supports data hiding.
I went for an interview. Then interviewer asked me that if Java supports data hiding by using private as datatype.
He said if we use setters and getters in that class then by using those setters and getters we can get that private data easily.
So how this is supporting data hiding here?
It may be possible that he was trying me catch me in trap. But I could not reply this.
What should I reply for this?
He was arguing that if "Data Hiding" is an OOP principle then aren't we breaking it by exposing via getters and setters. I think he wanted you to spell out the difference in principle between being able to access a data member directly vs. doing it via a getter or setter. In the former case a client of the class can mishandle the data, assign it a value that the class designer has not designed the class to handle (for example set the age of a student as 500).
In the latter (using a setter) the class designer has imposed certain restrictions on what values can be assigned to the data. In the age example the setter might be something like:
void setAge(int age) {
if(age<3 || age>100)
return;
this.age=age;
}
assuming that students of age below 3 and over 100 aren't allowed. So you are still hiding your data but allowing means to manipulate it in a way consistent with the logic of your module.
Very simple Example:
Version 1 of class could have getter like this.
public int getTotal() {
return total_;
}
Version 2 could do this
public int getTotal() {
return a + b;
}
We've changed how the class is implemented, but clients of the class don't need to change as well, because the data is hidden behind a getter.
Data hiding is bad term, better say data encapsulation. In java access to private members is done through accessors and mutators ( getter and setter), it is all about hiding and controlling access to your members so you can control how inner state of instance will be modified.
I think if you mention something about java reflection / metadata -> you will get bonus points
The class fields are hidden, if we declare them private. No doubt (we ignore nasty reflection tricks). If we want to make the values accessible, we provide access methods (getter/setter for example).
But there is no requirement to provide getters and setters for all fields or to name them according to fields (in general).
The class internals (the fields) are perfectly hidden.
protected String name;
public void setName(String newName){
if(newName.length() > 5) this.name = newName
}
public String getName(){
return this.name;
}
In this simple case the name attribute can be accessed by its name in this class and in all its children. If you want to set the value of name from an unrelated class than you will have to use the setName() method where you can apply some validation for example.
Here you can find any information you need about this special methods.
Be aware that any property of a class can be accessed if the mutators and accessors are public. This is one of the key points of the Java Bean concept and almost all java frameworks relate to this concept at one point or another.
What you are talking about seems to be Encapsulation. Basically the getters and setters allow you to expose class variables as you like and hide any others. Getters and Setters also allow you to perform any other necessary steps such as validation.
Getters and Setters can have different access modifiers themselves, so you can expose data to certain classes but not others by using different access modifiers.
I bet he was waiting that you will refer to "immutable" types also.
PD. private is no type, it is an access modifier.
The support for "data hiding" can be explained by the fact that the getter and setter methods are like gateways to the data.
It is only by convention - the JavaBeans convention to be exact - that it is expected from them to operate on the member they are named after. They could do anything else and it would still be perfectly compilable and legal java.
Maybe, he mean Encapsulation as information hiding.
If you make the setter & getter public/protected/default, then you could access the private members on different levels .. if you make setter&getter private then the data is really hidden. This last way to go makes no sense at all though
You may think about implement set/get methods in many different ways.
As some answers already pointed out, set/get don't have to actually set or return actual members.
For example, let's say you have a Coordinate class with set/get for (x, y). The inner implementation might be based on polar coordinates:
private double radius;
private double angle;
and the get/set for (x, y) do some coordinate transformation with sin and cos.
You could change the implementation of the class to any other system of coordinate at will and still just keep the set/get for (x, y) as public methods.
So, to sum up, my answer to the question would be: the public interface of a class might provide set/get, but the actual implementation can (and should) be hidden by making all members private (or protected). So we could say that having public set/get on private data is "implementation hiding" rather than data hiding.
Data Hiding and Encapsulation are frequently mistaken for security by first time oops learners. Its important to understand that data hiding and encapsulation have nothing to do with security.
These concepts exist to ensure that inheritance of a class A, from class B (class B extends A) does not inherit the "encapsulated" members.
I hope this kinda clarifies your confusion, and also motivates you to read and study more. Your question is very basic to the OOPS concepts. And the interviewer is not trying to corner, you but ask you very basic questions on OOPS. Study hard!!!
I want to force future users of a class to access a private member also from future code written in that class only through an accessor method (even through junit or anything like that).
is there a way to do it in java? can someone show an example if possible?
You cannot force to do that, but you can create a method and document that enforcement in the javadoc.
private int myMember;
/**
* ATTENTION: use this method instead of setting the member directly.
*/
public void setMyMember(int value) {
this.myMember = value;
}
Also, there is an alternative solution which might work. Use ThreadLocal, like this:
private final ThreadLocal<String> member = new ThreadLocal<String>();
public void setMember(final String value) {
member.set(value);
}
The member field is final and cannot be changed. Therefore, clients will be forced to call the setter directly.
As long as the field is part of the class, anyone can access it directly. This can be a problem when we try to force all (co-)authors to go through the getters/setters because those method do some conversion, checking or bookkeeping stuff. Like incrementing internal counters.
A general solution, that comes to mind: it could be possible by using annotations. You'd have to create an annotation (and the annotation processor code) to ensure, that it is a compile time error if the field is used outside of it's getter/setter method:
#GetterSetterAccessOnly
private int value;
If you want to prevent reflection you can use a SecurityManager. If this is not an option you can get the call stack with Thread.currentThread().getStackTrace() and check the caller is from your class.
Two problems with this are; the performance won't be great. Anything you can do in the method you can do externally so the simplest work around is to copy its contents without the check. ;)
I suggest you document your reason for not allowing access this way.
Make use of inheritance to hide the field:
Do your class with all the fields and getter/setters that you need. (You may make it abstract)
Do a child class, that inherits from the previews one, and since the field isn't accessible, you force the use of the getter/setter pair.
As you are talking about the accessing in the same class, they have all the freedom to access the private member directly as well as through accessor method if that member has. So basically you cannot prevent them using the member directly in the same class.
I am afraid there is no standard way to do that. If a user has access to a class instance, although a private member is declared private, permissions can be changed at runtime and accessed anyway.
You need a classloader that enforces permissions. You can make an OSGi Bundle and enforce a control policy over the instance of your objects exported as services through interfaces. However this will tie you to an OSGi container to run your application.
Well, if they have access to your code, they can do anything they want. In the worst case, they remove your getters and setters and just put in a public field instead ;)
But of course you can motivate them to not access the variable directly with an according design:
you should check whether the others should rather implement subclasses instead of changing the class itself. Then private fields are, of course, only accessed via setters and getters.
you could move the data into a different class, and use your getters and setters to access the data in the other class. Doing this just for the sake of not having the data directly in your class is maybe a bit counter-intuitive, but since you probably have a good reason why they shouldn't access that very data, it indicates a different responsibility. So refactoring to meet the SRP is a good idea anyways.
What is better practise and why: accessing base class variables through a protected field or a public getter on the private field.
(The getter will be public regardless)
If there's going to be a public getter anyway, why would you want to expose the field itself more widely than absolutely necessary? That means it's immediately writable by subclasses (unless it's final to start with).
Personally I like all my fields to be private: it provides a cleaner separation between API and implementation. I regard the relationship between a superclass and a subclass as similar to that of a caller and callee - changes to the underlying implementation shouldn't break subclasses any more than they should break callers. The name of a field is an implementation detail which shouldn't impact other classes.
Admittedly my view is occasionally seen as somewhat extreme...
You should always program against the public API of a class, that is, use the public methods.
The reason is simple. Someday in the future, you or someone else might want to change the implementation. This should always be possible. If you rely on instance variable, you limit yourself.
Also, when accessing the variable, you can not control if that variable is read-only nor can you add checks when this variable is changed.
If you use setters/getters, you can allways add validation, checking etc later on. You can also only provide a getter to make a variable read only.
Direct field access is not preferred. Use public or protected setters and getters.
The getter need not be public - if you wan to hide the data from "outsiders", but give the data to subclasses, use protected
Some of Sun's recommendations on controlling access to fields are here. Note that making a field protected exposes it to the package as well, not only to subclasses. Generally, as stated at the link above, fields should be private unless there is a very good reason not to do so.
Effective Java 2nd Edition says
Item 13: Minimize the accessibility of classes and members
The rule of thumb is simple: make each class or member as inaccessible as
possible. In other words, use the lowest possible access level consistent with the
proper functioning of the software that you are writing.
So if you are not sure why you need a protected class member (ie you don't need the field to be accessible to subclasses or classes in the same package), then declare it private. If you wish to set it from outside the class, then make a public setter.
However, if your member is final, then making it protected might be ok in some cases (ie it doesn't reveal sensitive information).
One potential security issue I would like to mention is that if you have an array declared protected final (even public final), the array reference is final (cannot be modified), but the objects held in the array are not final (an intruder could change the array contents).
If you know c++, you probably know that
const int * someMember
is different from
int * const someMember
The latter is like the final array in java.
The fix for the aforementioned security hole is to return a deep copy of the array or return it as a read only list.
Generally, you should use Sun's recommendations. There is one big exception: if you're programming for Android.
The reason is performance. With every virtual method invocation, there is overhead involved in using the lookup table to route the method to its object. This overhead is not involved when accessing a local variable.
Here are some links that explain this in a little more depth:
http://developer.android.com/training/articles/perf-tips.html#GettersSetters
http://blog.leocad.io/why-you-shouldnt-use-getters-and-setters-on-android/
It's important to know what you're trying to accomplish:
The field's value should be accessible to client code, using a public interface.
The field is meant to be used by subclasses.
In plain ol' Java, getters and setters accomplish both tasks. But Android is different. If you're doing #1, then you should use public getters and setters. If you're doing #2, then you should use protected fields. If you're doing both, use both.
I would like to present you with some arguments protecting "protected" fields in Java:
"You may favor accessing base class members using protected fields over public accessors in situation where you need to avoid value validation".
However if this is not the case, then private fields with public accessors should be used, to compliment hermetization.
The principle of getters and setters is to provide validation to the values inputted and outputted to the class member. However, in OOP languages, we operate on objects not classes. Base class and specialized class represent a single object, that is why it is perfectly fine to access specific class members over protected field.
Consider the following abstract example with a car:
- you have a base class Car and the derived class Porshe.
- Car class may have field like engine, which value is not set in Cars constructor (maybe the type of engine is known only after object initialization)
- You create a Porshe class object that contains some logic used to calculate engine type using some external data.
In this example, it is expected that engine field has a public getter, so car users know what engine the car has. However, there is no public setter as we expect car drivers not to temper with the engine! That is why, it is perfectly fine to make engine a protected field, so the Porshe class can set its value at some time in future.
Yes, some people will probably say "then use protected setter!".
And I will repeat: in OOP languages we work with objects not classes.
Single responsibility principle - yes, but as object not as class.
If you say: "at some point if we use protected fields over 3 or 5 inheritance levels, it may be troublesome to understand what happens to the field if each class performs some operation with it". And then I answer: That is another antipattern - your object is probably too big at this point and voids Single Responsibility principle.
Accessing protected fields from a subclass is one of the ways that inheritance violates encapsulation. Using the public API is better for this reason.
Will public access modifiers limits flexibility in changing code?If so give some examples..
If you can access the source code the modifiers can not limit your flexibility because you can change the modifiers.
If you can not access the source code you cannot extend or override any class or method marked final, you cannot access any method marked private, or default (without modifier) if your class is outside of the origin package, or protected if your class is outside of the origin package and not extends the original class
The first two answers from googling your question pretty much say it all
java.sun.com/docs/books/tutorial/java/javaOO/accesscontrol.html
www.java-samples.com/showtutorial.php?tutorialid=655
Now my perspective: I guess it is valuable to add that it is good practice to start with private by default and escalate to protected when if the class is extended; and public when you want to grant access to classes from different packages.
However, there is nothing stopping you from giving all members a public declaration. This does quite the opposite and increases your flexibility; with the caveat being that you sacrifice security. For example, if a 3rd party loads their own classes together with yours in the same classpath, and all the members in your class are public, they are easily able to modify the state of your classes. Numerous other examples.
So, unless you are absolutely unconcerned about security, escalate modifiers as and when needed.
Yes definitely public access modifiers limits flexibility in changing code with encapuslation feature in OOP . let me try explaining with an example . As you know the scope of the public access modifier can be accessed from any of the classes regardless of the package which they belong to . which results in Bad Object oriented design.
package com.app.access;
public class Car{
public int wheels;
public int lights;
// Method for how wheels rotate
// Method for how lights on
}
public class TestCar{
public static void main(String [] args) {
Car c = new Car();
c.wheels = -5; // Legal but bad 00 because we know it cannot have a negative value
}
}
Above example is Bad OO design which should be avoid by making a good practice providing private or protected access modifier to the instance variable and access through the Java bean compliant accessor methods take the form
get<propertyName> or for booleans is<propertyName> and set<propertyName>
provide a place to check and/or validate before returning or modifying a value.
Hope this Helps !!
There is no doubt that it is a bad idea to declare some class or member to be public when your OO design dictates that it should have more restricted access.
But does this limit your flexibility? I'd say yes.
Since this is homework, I'm not going to spell out the answer for you ... or give you examples that you can cut and paste. But consider Java's rules for overriding members in a subclass. Specifically, consider what you can and cannot do in terms of changing the access on the method.