My question involves specifically Java, abstract classes, and the use of protected data. I am being told that all the data should be private, and protected getters/setters used only.
Now, I understand we want to shield data from direct manipulation by casual users of the class, and that public data members in general are a questionable practice. I have looked at "Java protected fields vs public getters" ( Java protected fields vs public getters ), but I still am dubious that:
protected int i;
is worse in an abstract class than:
private int i;
protected int geti();
protected void seti(int j);
I am just not seeing the down side when the abstract class is there precisely to provide parent/common facility to the children classes, and the protected scope is meant to provide access to children, while protecting the data from casual users. I note in the question referenced above, that most of the answers seem to address the issue of why data in general should be private rather than public. I am trying to focus my question specifically on data existing in an abstract parent intended for use by the children. The sole reasonable comment I have heard to date is that using the parents protected data (e.g., int i above) leaves you with code in the child class that references a variable not declared in the child class. Less compelling is the argument (see Common protected data member in base class? ) that you may want to change the access some day, and now you have to honor your interface. This is an abstract class, and is intended to be extended 100% of the time.
Thanks! Specific Title/page# references to books are far more helpful that references to "..any basic Java programming text..."
========================================== 10-13-2010
This was as much a question about abstract classes as it is about protected data. I find it disappointing that the focus seems to have shifted in the responses to whether data hiding is a good thing in OOP (answer: yes). There's a lot of depth here involving the nature of the abstract class, and how it differs from a regular non-final class, and what possible advantages there might be for fixing the names and types of data-items in the abstract parent for use by the child classes. I think there is the possibility here for innovation and greater control being extended down from the abstract parent to the implementing child classes. I am concerned that general principles, such as the advantages of data-hiding, can become dogma, and inhibit innovation and the development of new patterns and ideas.
Thanks to all who contributed.
If the field is private and access is through getters and setters, you will be able to reimplement getters and setters (for instance, dropping the field and updating/reading the value from an external source), and thus change how the "field" works without touching any child classes.
Whether this is worth it, that's up to you.
Think of protected methods as an interface for subclasses, in the same way that public methods are an interface for everyone else.
Providing accessors enables the base class to maintain its state: there's no way a subclass would corrupt it without an intentional trick.
Having less access isn't a drawback, it's a benefit. Classes should always limit access to as much of their internal state as possible. Don't think of why internals should be hidden, instead think of why they should be exposed. In this case as in every case, unless there is a really good reason to expose the variable then don't expose it.
In Java protected members are accessible to all members in the same package in addition to any extending classes. Making the field private will prevent classes in the same package from directly accessing it.
As well there is the point that alex raised earlier.
If you don't need your child to directly access it, why would you let them ?
It isn't a down side to use protected. But if it isn't necessary, maybe it's better to avoid it and control access on your fields.
If someone subclasses your class, and puts the subclass in the same package as your current class, they may want to override your getters and setters. For example, they wantto make sure that i may only be set to a value greater than 1.
Other than that, it's really up to you. The convention is that there are getters and setters for everything though.
Information hiding is valuable, even among classes related by inheritance.
In addition to allowing re-implementation, as noted by alex above:
You can set breakpoints in methods.
You can add constraints in one place.
You want to use getters/setters because using protected int i; allows for field overriding (which you want to avoid at all costs).
You want to disallow field overriding because it works differently than method overriding. Field overriding does not make the overridden field inaccessible (the type of the reference determines which instance of the field you are working with).
Accessible fields should be final or in a class that is final.
public class OverridingFun {
public static class Base {
public int i = 1;
public int getI(){ return i; }
}
public static class A extends Base {
public int i = 2;
public int getI(){ return i; }
}
public static class B extends A {
public int i = 3;
public int getI(){ return i; }
}
public static void main(String [] args){
B b = new B();
A bAsA = b;
Base bAsBase = b;
System.out.println(b.getI());//3
System.out.println(bAsA.getI());//3
System.out.println(bAsBase.getI());//3
System.out.println(b.i);//3
System.out.println(bAsA.i);//2
System.out.println(bAsBase.i);//1
b.i = 4;
bAsA.i = 5;
bAsBase.i = 6;
System.out.println(b.i);//4
System.out.println(bAsA.i);//5
System.out.println(bAsBase.i);//6
}
}
At first glance this looks like something that would just make code hard to read but it has implications on functionality. Say the field does get overridden by a derived class, since setters are not being used, there is no way to automagically update the base field and no way to detect if someone has changed the base field (since the base value is still accessible) and update the derived field. It's easy to imagine that the base and derived states could get out of sync and that the errors would be hard to track down. Simply put it makes for a very brittle API.
Unfortunately there is no way to guard against this since the final keyword, which protects against overriding, also makes fields write-once. So no writable non-overloadable fields.
Personally I'm rather surprised the language designers allowed field overriding at all. The advantage of using setters is that each level can guaranty the integrity of it's own state and trust that derived classes haven't fouled it up. Field overriding is just asking for trouble.
Related
We can access Private data members using accessor method such as
private int num=5;
public int get_num()
{
return num;
}
and we can access the returned value from any class even though num is private data member.
So on Similar note cant we create accessor method that returns private methods?
I just had a thought about it,If we cannot do this please explain.Thank You
Private methods are created when refactoring your code. They are implementation details, which nobody outside needs to know. They are used inside public methods, which are supposed to provide the functionality you want to provide to your client(each public method can be called an API which is used/consumed by other classes i.e. its clients).
Access modifiers are provided to help you achieve proper abstraction. So anything marked private is directly accessible only inside your class. But if you want someone outside to read/write its value, you expose it via getters/setters. Similarly private methods are not accessible outside the class. But nobody is stopping you from creating public method that only calls this private method. This way you do achieve access to private method. But it would be a very poor design.
You can access private method via public method. This is sometimes used to wrap complicated private method and expose simpler, public API.
class Delegator {
private void doPrivateStuff(int param) { ... }
public void doStuffOnce() {
doPrivateStuff(1);
}
public void doStuffIfConditionIsMet() {
if(condition) {
doPrivateStuff(1);
}
}
}
You can also access private methods using reflection.
http://tutorials.jenkov.com/java-reflection/private-fields-and-methods.html
Because the accessor is public, it can be accessed from outside the class; even if it returns private data.
The access modifier of the returned data isn't relevant, only the access modifier of the method matters.
If you created a public method that returned a reference to a private method, yes, you could then call the private method from outside the class. That would entirely defeat the purpose of making the method private however.
You my be wondering "why make a public getter to a private variable". The answer is that although it's possible to retrieve the private data, it isn't possible (unless you create a public setter as well) to change the public data. This assumes that the private days is immutable. If it's mutable, retuning a reference to private data negates any protection you get from making the variable private.
TL;DR
Accessing private methods violates the basic object oriented principle of encapsulation. The question is not "can we access a private method?" but "should we ever do it?". It contradicts the principle of information hiding and it breaks the contract an object "offers" to its consumers. Objects or classes that enforce you to do that should be considered poorly designed.
Why you shouldn't access private members
First a classes should implement a part of your domain logic that is so closely related that there are little interactions necessary with the outside world to fulfill its duties (this is called high cohesion). You then define a public interface for your class / object with functionality that you expose to the outside world - consumers of your object must only use this interface (this is called loose coupling).
Private methods can be seen as a way to structure your code inside your class in a better readable way - they are not intended to be shared with the outside world. Consider them as a "safe space" for the developer of the class to make arbitrary changes without breaking the contract. That's the reason why there can be bad side effects if you actually access private methods: your code is likely to break it the developer of the class decides to change the implementation of such a method. Effective Java, Chapter 4, Item 13 explains this for protected members:
For members of public classes, a huge increase in accessibility occurs when the access level goes from package-private to protected. A protected member is part of the class's exported API and must be supported forever. Also, a protected member of an exported class represents a public commitment to an implementation detail.
Exceptions
The only exception I know from the rule of "not accessing private members outside of an object" is in testing, when you either want to reset a certain variable (e.g. a Singleton) or you want to facilitate the testing of complex logic by testing the private parts of the implementation and hence reducing complexity in testing.
Let's take an example:
public interface Testerface {
default public String example() {
return "Hello";
}
}
public class Tester implements Testerface {
#Override
public String example() {
return Testerface.super.example() + " world!";
}
}
public class Internet {
public static void main(String[] args) {
System.out.println(new Tester().example());
}
}
Simply enough, this would print Hello world!. But say I was doing something else with the return value of Testerface#example, for instance initializing a data file and returning a sensitive internal value that shouldn't leave the implementing class. Why does Java not allow access modifiers on default interface methods? Why can't they be protected/private and potentially elevated by a subclass (similar in how a class that extends a parent class can use a more visible modifier for an overridden method)?
A common solution is moving to an abstract class however in my specific case, I have an interface for enums, so that does not apply here. I imagine it was either overlooked or because the original idea behind interfaces that they are a "contract" of available methods, but I suppose I want input as to what's going on with this.
I've read "Why is “final” not allowed in Java 8 interface methods?", which states:
The basic idea of a default method is: it is an interface method with a default implementation, and a derived class can provide a more specific implementation
And it sounds to me like visibility wouldn't break that aspect at all.
As with the linked question since it looks like it had trouble being closed, an authoritative answer would be appreciated in this matter, rather than opinion-based ones.
As we saw in What is the reason why “synchronized” is not allowed in Java 8 interface methods? and Why is "final" not allowed in Java 8 interface methods?, extending interfaces to define behavior is more subtle than it might first appear. It turns out that each of the possible modifiers has their own story; its not simply a matter of blindly copying from how classes work. (This is at least obvious in hindsight, as tools for OO modeling that work for single inheritance do not automatically work for multiple inheritance.)
Let's start with the obvious answer: interfaces have always been restricted to only having public members, and while we added default methods and static methods to interfaces in Java 8, that doesn't mean we have to change everything just to be "more like" classes.
Unlike with synchronized and final, which would have been serious mistakes to support for default methods, weaker accessibilities, especially private, are reasonable features to consider. Private interface methods, whether static or instance (note that these would not be defaults, since they do not participate in inheritance) are a perfectly sensible tool (though they can be easily simulated by nonpublic helper classes.)
We actually did consider doing private interface methods in Java 8; this was mostly something that just fell off the bottom of the list due to resource and time constraints. It is quite possible this feature might reappear on the to-do list some day. (UPDATE: private methods in interfaces were added in Java 9.)
Package and protected methods, however, are more complicated than they look; the complexity of multiple inheritance and the complexity of the true meaning of protected would interact in all sorts of no-so-fun ways. So I wouldn't hold your breath for that.
So, the short answer is, private interface methods is something we could have done in 8, but we couldn't do everything that could have been done and still ship, so it was cut, but could come back.
I am reading a book about Java and it says that you can declare the whole class as final. I cannot think of anything where I'd use this.
I am just new to programming and I am wondering if programmers actually use this on their programs. If they do, when do they use it so I can understand it better and know when to use it.
If Java is object oriented, and you declare a class final, doesn't it stop the idea of class having the characteristics of objects?
First of all, I recommend this article: Java: When to create a final class
If they do, when do they use it so I can understand it better and know when to use it.
A final class is simply a class that can't be extended.
(It does not mean that all references to objects of the class would act as if they were declared as final.)
When it's useful to declare a class as final is covered in the answers of this question:
Good reasons to prohibit inheritance in Java?
If Java is object oriented, and you declare a class final, doesn't it stop the idea of class having the characteristics of objects?
In some sense yes.
By marking a class as final you disable a powerful and flexible feature of the language for that part of the code. Some classes however, should not (and in certain cases can not) be designed to take subclassing into account in a good way. In these cases it makes sense to mark the class as final, even though it limits OOP. (Remember however that a final class can still extend another non-final class.)
In Java, items with the final modifier cannot be changed!
This includes final classes, final variables, and final methods:
A final class cannot be extended by any other class
A final variable cannot be reassigned another value
A final method cannot be overridden
One scenario where final is important, when you want to prevent inheritance of a class, for security reasons. This allows you to make sure that code you are running cannot be overridden by someone.
Another scenario is for optimization: I seem to remember that the Java compiler inlines some function calls from final classes. So, if you call a.x() and a is declared final, we know at compile-time what the code will be and can inline into the calling function. I have no idea whether this is actually done, but with final it is a possibility.
The best example is
public final class String
which is an immutable class and cannot be extended.
Of course, there is more than just making the class final to be immutable.
If you imagine the class hierarchy as a tree (as it is in Java), abstract classes can only be branches and final classes are those that can only be leafs. Classes that fall into neither of those categories can be both branches and leafs.
There's no violation of OO principles here, final is simply providing a nice symmetry.
In practice you want to use final if you want your objects to be immutable or if you're writing an API, to signal to the users of the API that the class is just not intended for extension.
Relevant reading: The Open-Closed Principle by Bob Martin.
Key quote:
Software Entities (Classes, Modules,
Functions, etc.) should be open for
Extension, but closed for
Modification.
The final keyword is the means to enforce this in Java, whether it's used on methods or on classes.
The keyword final itself means something is final and is not supposed to be modified in any way. If a class if marked final then it can not be extended or sub-classed. But the question is why do we mark a class final? IMO there are various reasons:
Standardization: Some classes perform standard functions and they are not meant to be modified e.g. classes performing various functions related to string manipulations or mathematical functions etc.
Security reasons: Sometimes we write classes which perform various authentication and password related functions and we do not want them to be altered by anyone else.
I have heard that marking class final improves efficiency but frankly I could not find this argument to carry much weight.
If Java is object oriented, and you declare a class final, doesn't it
stop the idea of class having the characteristics of objects?
Perhaps yes, but sometimes that is the intended purpose. Sometimes we do that to achieve bigger benefits of security etc. by sacrificing the ability of this class to be extended. But a final class can still extend one class if it needs to.
On a side note we should prefer composition over inheritance and final keyword actually helps in enforcing this principle.
final class can avoid breaking the public API when you add new methods
Suppose that on version 1 of your Base class you do:
public class Base {}
and a client does:
class Derived extends Base {
public int method() { return 1; }
}
Then if in version 2 you want to add a method method to Base:
class Base {
public String method() { return null; }
}
it would break the client code.
If we had used final class Base instead, the client wouldn't have been able to inherit, and the method addition wouldn't break the API.
A final class is a class that can't be extended. Also methods could be declared as final to indicate that cannot be overridden by subclasses.
Preventing the class from being subclassed could be particularly useful if you write APIs or libraries and want to avoid being extended to alter base behaviour.
In java final keyword uses for below occasions.
Final Variables
Final Methods
Final Classes
In java final variables can't reassign, final classes can't extends and final methods can't override.
Be careful when you make a class "final". Because if you want to write an unit test for a final class, you cannot subclass this final class in order to use the dependency-breaking technique "Subclass and Override Method" described in Michael C. Feathers' book "Working Effectively with Legacy Code". In this book, Feathers said, "Seriously, it is easy to believe that sealed and final are a wrong-headed mistake, that they should never have been added to programming languages. But the real fault lies with us. When we depend directly on libraries that are out of our control, we are just asking for trouble."
If the class is marked final, it means that the class' structure can't be modified by anything external. Where this is the most visible is when you're doing traditional polymorphic inheritance, basically class B extends A just won't work. It's basically a way to protect some parts of your code (to extent).
To clarify, marking class final doesn't mark its fields as final and as such doesn't protect the object properties but the actual class structure instead.
TO ADDRESS THE FINAL CLASS PROBLEM:
There are two ways to make a class final. The first is to use the keyword final in the class declaration:
public final class SomeClass {
// . . . Class contents
}
The second way to make a class final is to declare all of its constructors as private:
public class SomeClass {
public final static SOME_INSTANCE = new SomeClass(5);
private SomeClass(final int value) {
}
Marking it final saves you the trouble if finding out that it is actual a final, to demonstrate look at this Test class. looks public at first glance.
public class Test{
private Test(Class beanClass, Class stopClass, int flags)
throws Exception{
// . . . snip . . .
}
}
Unfortunately, since the only constructor of the class is private, it is impossible to extend this class. In the case of the Test class, there is no reason that the class should be final. The Test class is a good example of how implicit final classes can cause problems.
So you should mark it final when you implicitly make a class final by making it's constructor private.
One advantage of keeping a class as final :-
String class is kept final so that no one can override its methods and change the functionality. e.g no one can change functionality of length() method. It will always return length of a string.
Developer of this class wanted no one to change functionality of this class, so he kept it as final.
The other answers have focused on what final class tells the compiler: do not allow another class to declare it extends this class, and why that is desirable.
But the compiler is not the only reader of the phrase final class. Every programmer who reads the source code also reads that. It can aid rapid program comprehension.
In general, if a programmer sees Thing thing = that.someMethod(...); and the programmer wants to understand the subsequent behaviour of the object accessed through the thing object-reference, the programmer must consider the Thing class hierarchy: potentially many types, scattered over many packages. But if the programmer knows, or reads, final class Thing, they instantly know that they do not need to search for and study so many Java files, because there are no derived classes: they need study only Thing.java and, perhaps, it's base classes.
Yes, sometimes you may want this though, either for security or speed reasons. It's done also in C++. It may not be that applicable for programs, but moreso for frameworks.
http://www.glenmccl.com/perfj_025.htm
think of FINAL as the "End of the line" - that guy cannot produce offspring anymore. So when you see it this way, there are ton of real world scenarios that you will come across that requires you to flag an 'end of line' marker to the class. It is Domain Driven Design - if your domain demands that a given ENTITY (class) cannot create sub-classes, then mark it as FINAL.
I should note that there is nothing stopping you from inheriting a "should be tagged as final" class. But that is generally classified as "abuse of inheritance", and done because most often you would like to inherit some function from the base class in your class.
The best approach is to look at the domain and let it dictate your design decisions.
As above told, if you want no one can change the functionality of the method then you can declare it as final.
Example: Application server file path for download/upload, splitting string based on offset, such methods you can declare it Final so that these method functions will not be altered. And if you want such final methods in a separate class, then define that class as Final class. So Final class will have all final methods, where as Final method can be declared and defined in non-final class.
Let's say you have an Employee class that has a method greet. When the greet method is called it simply prints Hello everyone!. So that is the expected behavior of greet method
public class Employee {
void greet() {
System.out.println("Hello everyone!");
}
}
Now, let GrumpyEmployee subclass Employee and override greet method as shown below.
public class GrumpyEmployee extends Employee {
#Override
void greet() {
System.out.println("Get lost!");
}
}
Now in the below code have a look at the sayHello method. It takes Employee instance as a parameter and calls the greet method hoping that it would say Hello everyone! But what we get is Get lost!. This change in behavior is because of Employee grumpyEmployee = new GrumpyEmployee();
public class TestFinal {
static Employee grumpyEmployee = new GrumpyEmployee();
public static void main(String[] args) {
TestFinal testFinal = new TestFinal();
testFinal.sayHello(grumpyEmployee);
}
private void sayHello(Employee employee) {
employee.greet(); //Here you would expect a warm greeting, but what you get is "Get lost!"
}
}
This situation can be avoided if the Employee class was made final. Just imagine the amount of chaos a cheeky programmer could cause if String Class was not declared as final.
Final class cannot be extended further. If we do not need to make a class inheritable in java,we can use this approach.
If we just need to make particular methods in a class not to be overridden, we just can put final keyword in front of them. There the class is still inheritable.
Final classes cannot be extended. So if you want a class to behave a certain way and don't someone to override the methods (with possibly less efficient and more malicious code), you can declare the whole class as final or specific methods which you don't want to be changed.
Since declaring a class does not prevent a class from being instantiated, it does not mean it will stop the class from having the characteristics of an object. It's just that you will have to stick to the methods just the way they are declared in the class.
Android Looper class is a good practical example of this.
http://developer.android.com/reference/android/os/Looper.html
The Looper class provides certain functionality which is NOT intended to be overridden by any other class. Hence, no sub-class here.
I know only one actual use case: generated classes
Among the use cases of generated classes, I know one: dependency inject e.g. https://github.com/google/dagger
Object Orientation is not about inheritance, it is about encapsulation. And inheritance breaks encapsulation.
Declaring a class final makes perfect sense in a lot of cases. Any object representing a “value” like a color or an amount of money could be final. They stand on their own.
If you are writing libraries, make your classes final unless you explicitly indent them to be derived. Otherwise, people may derive your classes and override methods, breaking your assumptions / invariants. This may have security implications as well.
Joshua Bloch in “Effective Java” recommends designing explicitly for inheritance or prohibiting it and he notes that designing for inheritance is not that easy.
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.
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?