When to make instance variables private? - java

I'm trying to understand the usage for getter/setter methods in a class. Let's say we have a class called A with some public instance variables followed by a constructor with parameters where arguments were passed from another class(main) to it. Inside the constructor we let those instance variables equal what was passed.
Now if this class were to be used by another programmer, nothing would stop them from directly accessing/changing the instance variables to something that isn't valid. By making the instance variables private we can eliminate access to those variables. However if we wanted to have those instance variables updated/changed indirectly or under some specific condition or perhaps just letting the person have access to the instance variable, we would create a getter/setter pair for this purpose.
Benefits?:
1.Change instance variable only under certain valid reasons under the set() method
2.So that we can show what the instance variable actually is without giving the programmer who is using this class the ability to change it.
Is this a correct interpretation?

Encapsulation – refers to keeping all the related members (variables and methods) together in an object. Specifying
member variables as private can hide the variables and methods. Objects should hide their inner workings from the
outside view. Good encapsulation improves code modularity by preventing objects interacting with each other in
an unexpected way, which in turn makes future development and refactoring efforts easy.
Being able to encapsulate members of a class is important for security and integrity. We can protect variables from
unacceptable values. The sample code above describes how encapsulation can be used to protect the MyMarks object
from having negative values. Any modification to member variable vmarks can only be carried out through the setter
method setMarks(int mark). This prevents the object MyMarks from having any negative values by throwing an
exception.

Your interpretation is correct. Also (off the top of my head):
It allows the implementation of the class to change (eg if you wish to remove the field and replace it) without forcing consumers to interact with your class any differently.
It allows AOP frameworks to intercept calls to your get / set method.
You can specify permissions via annotations for access to methods.

Yes, your interpretation is correct. But it's because limits of language. For instance in python you don't need write everytime getter or setter, because you can override behavior of member variables. For example:
class MyClass:
def __init__(self, myproperty):
self.myproperty = myproperty
And if everybody use it in way like:
print(new MyClass("test").myproperty)
you can still change behavior of you getter:
class MyClass:
def __init__(self, myproperty):
self._myproperty = myproperty
#property
def myproperty(self):
return self._myproperty + " changed behavior"
or even of setter without touch code what use you class:
#myproperty.setter
def myproperty(self, myproperty):
if len(myporperty) > 0:
self._myproperty = myproperty
See property reference for better example.

if an instance variable is to be used only by methods defined with in its class, then it should be made it as private.If an instance variable must be within certain bounds, then it should be private and made available only through accessor methods[getter as well as Setter] Methods.

Related

What is the purpose of creating a class-level variable in Java?

I was writing a piece of code that goes like this,
public class Grades
{
public int marks; // what's the purpose of this?
...
...
}
Objects are data and methods encapsulated together into a single software component.
Classes are templates ("cookie cutters") from which you can create one or more instances in memory ("cookies"). Each one is independent; each can have its own state.
By declaring the variable outside of any methods you've made it an attribute of the class. This means that any method in the class can access it, and depending on its encapsulation (public/private/protected/package private) other classes can access it as well.
As for that specific variable's purpose in that specific class, that cannot be determined without seeing more code.

Is there a point to having a class with all non-static methods but no non-static fields? (or all static fields and methods along with a constructor)

I am looking at other peoples' code.
I see a class with no non-static fields but in which most of the methods are non-static, requiring you to make an object to access methods that effectively operate statically.
Is there a possible reason for this, that I am just not understanding?
EDIT
Someone asked for examples. Here is some more info.
For instance there is a file manager class. The only fields are static and are Comparators. There are some methods to do things like sort files in a list, count files, copy files, move files to an archive folder, delete files older than a certain time, or create files (basically take a base name as string, and return a File with given base name and date/time tacked on the end.)
9 non-static methods
5 static methods
I don't see a particular rhyme reason for the ones that are static vs non.
One particularly odd thing is that there are two methods for removing files. One that removes a file no matter what, and one that only removes it if it is empty. The former is a static method while the latter is not. They contain the same exact code except the later first checks if the file.length is 0.
Another odd one is a class that does encryption - all fields and methods are static but it has a constructor that does nothing. And an init() method that checks if a static variable contains an object of itself and if not instantiates an object of itself into that field that is then never actually used. (It seems this is done with a lot of classes - init methods that check for an object of itself in a static variable and if not instantiate itself)
private static File keyfile;
private static String KEYFILE = "enc.key";
private static Scrambler sc;
It has methods to encrypt and decrypt and some methods for dealing with key and file.
Does this make sense to anyone? Am I just not understanding the purpose for this stuff? Or does it seem weird?
Objects don't have to have state. It's a legitimate use case to create an instance of a class with only behaviour.
Why bother to create an instance ? So you can create one and pass it around e.g. imagine some form of calculator which adheres to a particular interface but each instance performs a calculation differently. Different implements of the interface would perform calculations differently.
I quite often create classes with non-static methods and no members. It allows me to encapsulate behaviour, and I can often add members later as the implementation may demand in the future (including non-functionality related stuff such as instrumentation) I don't normally make these methods static since that restricts my future flexibility.
You can certainly do it that way. You should look carefully at what the instance methods are doing. It's perfectly okay if they're all operating only on parameters passed in and static final static class constants.
If that's the case, it's possible to make all those methods static. That's just a choice. I don't know how the original developers would justify either one. Maybe you should ask them.
Let me rephrase this question a bit,
Even though methods are non-static why would one declare fields as static?
I have taken below quoting from Java Docs,
Sometimes, you want to have variables that are common to all objects. This is
accomplished with the static modifier. Fields that have the static modifier in their declaration are called static fields or class variables. They are associated with the class, rather than with any object. Every instance of the class shares a class variable, which is in one fixed location in memory. Any object can change the value of a class variable, but class variables can also be manipulated without creating an instance of the class.
For example, suppose you want to create a number of Bicycle objects and assign each a serial number, beginning with 1 for the first object. This ID number is unique to each object and is therefore an instance variable. At the same time, you need a field to keep track of how many Bicycle objects have been created so that you know what ID to assign to the next one. Such a field is not related to any individual object, but to the class as a whole.
For Bicycle example, kindly refer the Java Docs.
Making all methods non-static allows you to override them. This makes it a lot easier to use this class in testing, because instead of the actual implementation you can use a mock that behaves as you want it for the tests. Static methods are, in my book, a code smell and should be avoided unless there's a good reason (e.g. quite trivial utility methods).
Also, at some point in the future you might want to change the behaviour of the methods in some situation, e.g. in the form of a strategy.
In the case of your encryption class, you might want to hand your class an instance of the encryption class to handle encrypting/decrypting, but be able to configure the details in some other place. That would allow you to change the algorithm and much more easily test your own code without also having to test the encryption.

Proper way to declare field that needs to exist in sub-classes?

Say I have a class Animal and then a bunch of sub-classes that extend Animal. Say I want to have a common field called name that should also exist in each child class. What is the proper way to include and initialize this field in each sub-class?
1) Declare the field in the parent as protected, and then initialize it inside of each sub-class. If I do it this way, is it proper to refer to the field as super.variable or simply variable? Personally to me, using super makes it more obvious that the field is declared in the parent. (This is what I am currently doing)
2) Declare the field in the parent as private and then create getters and setters to access the field
3) Just declare and initialize the same variable in each sub-class
4) Another method I'm missing?
Thanks for the help. I understand this question is fairly basic, but I'm curious of what the most proper style is.
Edit:
I'm not to sure if you guys will see this, but here is a follow up question.
Is there any good way to ensure that the sub-classes initialize the field?
The answer depends on whether you need to control access to that field for correctness (e.g., to make sure that some other field gets updated at the same time). If it's okay for subclasses to twiddle the field directly, then just use protected. If you need to perform additional checks or actions whenever the field is set, you should make it private to the superclass and make the subclass use the setter to ensure your logic is run. You shouldn't duplicate the field if you know that it'll always be needed; if you're not sure, then you should consider using an interface Animal and putting the field on an AbstractAnimal implements Animal.
In Java, you don't use super for anything except to call the superclass's version of a method. Just access protected fields directly; that's what they're there for, and your development environment will keep track of where they're declared if you need to know.
I vote for 2:
Create a private field, and have setters and getters (which can be protected to make them accessible only to subclasses).
Other options if you don't need a setter (just a getter):
4) Abstract getter and leave it up to the subclass how to implement it
5) private final field, set by abstract class constructor, and a getter.
I always make fields protected fields, since this helps debuggability & extensibility, and put public getters & setters on them to make a 'property'.
(Private fields in various open-source libraries, Swing components etc have repeatedly been a hindrance to me when trying to do quite legitimate debugging/ extension engineering. So I'm fairly anti- them.)
If I'm concerned about traceability, where there is possible behaviour or errors involved (such as values being got & cached), I might access the variable in subclasses via the getter.
I always use this.name when writing to variables -- it works well for code clarity, and it simplifies parameter-naming in setters. (Use just name for the parameter & this.name for the field.)
I don't use this when reading variables -- it's the writes I want to be clear about. For collections, I suffix the field with List or map or whatever ie childList -- but the parameter and locals are "children".
I never use super when referring to variables. Super would only make sense to disambiguate inherited & declared variables with the same name, which you can legally do -- but is almost guaranteed to be erroneous for code style, clarity & tends to lead to bugs.
I also like to make most properties mutable -- rather than settable only at construction. This helps if you ever want to use Hibernate, or persist the data. Over-reliance on constructor initialization tends to evolve into difficulties -- large & brittle call-signatures, inability to use the class for partly-formed data or "special value" answers, and order-of-init problems.
I think it depends on the situation. If the name field should be publicly accessible, I would declare the field as private and then make public get/set methods. Sometimes you want to expose fields on the base class as part of the public interface of the derived classes.
If the name field should only be used inside the derived classes I would just go with a protected field.
If you want to be sure that a subclass initializes a field add a parameter in the base class constructor, then initialize the field in the base class using the argument supplied by the derived classes constructor.
I usually using option 2 (private + accessors - protected,not necessary public) to have a chance to customize variable access.
About your edit: Force in constructor name if it is a mandatory requirement
Animal(String name) {
this.name = name;
}
or
String getName() {
if(null == name){
name = initializeName();
}
return name;
}
and make initializeName() abstract

Difference between using a method in a class to return a value and referencing the exact value itself

Let's say I have a separate GUI class that has a public boolean called "guiWait" and also has a boolean method that returns guiWait.
What's the difference between:
while(gui.guiWait)...
and
while(gui.getGuiWait())...
The difference is visibility. When you make guiWait public to be used like the first example, outside callers can modify the value. If you use a method and make the variable private, callers cannot modify the guiWait variable (although they can modify the object it references if it's mutable). Furthermore, if you make a habit of using getters and setters, then later on if you need to add logic to the getting or setting process (such as you need to make the value derived from some other new field), you already have the methods and won't break any caller's code by making the variable private. So it's considered "best practice" to always use getters and setters in Java.
If guiWait is a public boolean, there is no point in having a "getter" method for it. If it were private or protected, then it'd be a different story. The private-getter method is more flexible because you can change the implementation of the "getting" of that variable, and add checks or whatever inside the method. Private getters/setters also make things clearer and establish which things should be seen by other classes and which are only meant to be used inside a single class they are apart of. If you find you do need a getter for a specific member variable (need some kind of verification or checking), which is very common, then it would be inconsistent to do it just for that variable.
The core concept of OOP is encapsulation. The getter and setter methods (eg. your getguiWait() method) are used so that nobody is able to access the internal fields of an object. This way no one else is able to set the internal fields to an inconsistent/abnormal value. By using the "getter" and "setter" methods (and hiding the inner fields by using private), you ensure that anyone willing to set or get a field will have to go through the checks that you have put up. Example Class Cat can have age as its field. In the setter method you would check that the user input value is not negative. If you allow the age field to be public, someone could potentially set it to negative which would make no sense.
Its the pure concept of Data Encapsulation in JAVA.
A language mechanism for restricting access to some of the object's components.
A language construct that facilitates the bundling of data with the methods (or other functions) operating on that data.
http://www.tutorialspoint.com/java/java_encapsulation.htm

How would i access Object properties an object method?

What is the "correct" way to access an object's properties from within an object method that is not a getter/setter method?
Getter/Setter is the recommended way of accessing properties of an object. Otherwise you to have to use public properties, but public properties are not recommended.
If a classes' properties don't have getters and they are not visible (e.g. not public), that means that the class is designed so that you can't access them. In that case, there is no proper way to access them.
Flipping this around, if you are designing a class and you intend that other classes can access its attributes, you ought to provide getters. You could alternatively declare the attributes to be public, protected or package private, but that makes your abstraction leaky and has a number of undesirable consequences.
If you are asking how one of an object's methods should access its own attributes, the simple answer is whichever way is most convenient. If the class has getters, you could call them. Alternatively, you could just access the attributes directly. The problems of leaky abstraction don't apply in this case because the method accessing the state is inside the abstraction boundary.
This is mostly a matter of preference.
I personally prefer not to use the getters and setters in my object. This increases readability, allows me to change my getters and settings to return copies (of lists mostly) without it changing my own object. If you do something special in your getter then you can make a helper method that is used by both your getter and your other functions. This will go wrong if your classes get too large though (so don't make large classes). I don't like how using a getter setter hides the side effects inside the object (unlike for external users, they should be hidden from any side effects inside the object), when you want to have the side effects, give the private method a clear name indiciting it has them.
First off I'll answer the question as is:
What is the "correct" way to access an object's properties from within an object method that is not a getter/setter method?
When you are within an object, you can reference the properties directly where the method is part of the object. For example:
public class testClass() {
public int x;
private someMethod() {
x = 4;
}
}
To answer the comment:
I think the question can be reformulated: Should I use getters and setters when implementing my object methods? Or should I access member variables directly?
You should always hide the internal data and other implementation details within a class as much as possible; seperating the API from the implementation (a.k.a encapsulation). Encapsulation decouples the modules thereby allowing them to be developed, tested and modified in isolation.
Generally, you should use the lowest access modifier possible (e.g. private, protected, package-private) whilst maintaining functionality for the application you're writing. The benefits of designing and devloping this way is that you can change implementation details without breaking code that uses the modules. If you make everything public, and other people are using your classes, you are forced to support it forever maintaining compatibility - or until they change their implementation that is using your modules.
Instance fields should never be public as you give up the ability to limit the values that can be stored in the field, and if it is a mutable object, you open your object up for misuse (see here). It is important to note too that classes with public mutable fields are not thread-safe. It is also important to note that instance fields that are declared public static final but are mutable objects can also be modified and can be a security risk.
Basically, in public classes - always use accessor methods, not public fields. It allows you to protect your mutable objects from modification outside of the class (be it intentionally or unintentionally) and allows you to change implementation detail later without harming your clients.

Categories