I realize this probably cannot be answered, but I'm looking for whether there is some sort of guidance about whether to use private members directly or public accessors inside class methods.
For example, consider the following code (in Java, but it would look very similar in C++):
public class Matrix {
// Private Members
private int[][] e;
private int numRows;
private int numCols;
// Accessors
public int rows(){ return this.numRows; }
public int cols(){ return this.numCols; }
// Class Methods
// ...
public void printDimensions()
{
// [A] Using private members
System.out.format("Matrix[%d*%d]\n", this.numRows, this.numCols);
// [B] Using accessors
System.out.format("Matrix[%d*%d]\n", this.rows(), this.cols());
}
The printDimensions() function illustrates two ways to get the same information, [A] using private members (this.numRows, this.numCols) or [B] via accessors (this.rows(), this.cols()).
On one hand, you may prefer using the accessors since there is no way you could inadvertently change the value of the private member variables. On the other, you may prefer accessing the private members directly in hopes that it would remove the unnecessary function call.
I guess my question is, is either the de-facto standard or preferred?
It's a style call. I prefer to use accessors, because IMHO the function call overhead is small enough that in most cases it doesn't matter, and this usage preserves the data abstraction. If i later want to change the way the data is stored, i only need to change the accessors, instead of hunting for all the places where i touched the variables.
I don't feel strongly about it, though, and i would break this "rule" if i thought i had a good reason to.
IMHO, accessors are more a matter of structure and data management rather than accessors per se. Sometimes, you need to preprocess some data before returning it. Think about this example:
public class Foo {
private List<Bar> bars = null;
//Methods and stuff
public List<Bar> getBars() {
if(bars == null)
bars = SomeClass.loadBars();
// You can also use
// setBars(SomeClass.loadBars());
return bars;
}
}
In this case, your getter is not only wrapping your field, but returning an initialized field whenever you invoke it. Using the accessors inside a class gives the same benefits that for outsiders, you abstract yourself from the particular details of a field and you can obtain it after processing it.
On the other hand, if your field is returned directly (say, a String) it doesn't matter if you use a get or you don't, but you might want to use a get to respect a standard in your code.
In the end, it all boils down to coding style.
I have other objects, including subclasses of the object, use the accessors, but have the object itself use the fields. That way there is a clear distinction between the internals and the interface with the rest of the world. Hiding the contents of the class from itself seems unnecessary and potentially confusing. If something really benefits from having its implementation hidden from other parts of the object then break it out into a separate object.
Related
Common design practice is to make instance variables private and have public getters and setters to access them. But many times I have seen code samples on the internet that have constructors that assign values directly to the private instance variable instead of using the setters inside constructors. Am I missing something?
public class Person{
private String name;
public Person(String name){
//is this right, seems like the whole encapsulation purpose is defeated
this.name = name;
//shouldn't this be used
setName(name);
}
public String getName(){
return this.name;
}
public void setName(String name){
this.name = name;
}
}
You are not missing anything. What you do depends entirely on your situation. However, consider this:
It is very common to do parameter validation in a setter. For example, let's say I have a class with field that can hold a value 0 through 10 (the "throws" is unnecessary for the exception type below but I include it for clarity):
public class Example {
private int value;
public Example () {
}
public final int getValue () {
return value;
}
public final void setValue (int value) throws IllegalArgumentException {
if (value < 0 || value > 10)
throw new IllegalArgumentException("Value is out of range.");
}
}
Here, setValue() validates 'value' to make sure it sticks to the rules. We have an invariant that states "an Example will not exist with an out of range value". Now let's say we want to make a constructor that takes a value. You might do this:
public class Example {
...
public Example (int value) {
this.value = value;
}
...
}
As you can see, there is a problem. The statement new Example(11) would succeed, and now an Example exists that breaks our rules. However, if we use the setter in the constructor, we can conveniently add all parameter validation to the constructor as well:
public class Example {
...
public Example (int value) throws IllegalArgumentException {
setValue(value); // throws if out of range
}
...
}
So there are many benefits to this.
Now, there are still cases when you might want to assign values directly. For one, maybe you don't have setters available (although I would argue that creating private or package private setters is still desirable, for the reasons mentioned above, for reflection/bean support if necessary, and for ease of validation in more complex code).
Another reason might be that perhaps you have a constructor that knows, somehow, ahead of time that valid values will be assigned, and therefore doesn't need validation and can assign variables directly. This is usually not a compelling reason to skip using setters though.
However, all-in-all, it's generally a good idea to use the setters everywhere when possible, it will usually lead to cleaner and clearer code that is easier to maintain as complexity increases.
Most of the examples you see where people set variables directly are just people being "lazy" - which is perfectly acceptable if the situation warrants it (perhaps you're writing a quick test program or application and don't want to implement a bunch of setters, for example). There's nothing wrong with that as long as you keep the big picture in mind and only be "lazy" when it's appropriate.
Something I'd like to add based on some of the other answers here: If you override a setter in a subclass, and the data you are setting breaks invariants that the base class assumes, then either the relevant setters should be made final or the base class should not make those assumptions. If overriding setters breaks base class invariants then there is a bigger issue at hand.
You'll notice the getter/setter is final in the above example. This is because our rule is that "any Example must have a value from 0 to 10". This rule therefore extends to subclasses. If we did not have that rule and if an Example could take on any value, then we would not need a final setter and could allow subclasses to override.
Hope that helps.
Sometimes when you would want make the class immutable, it is just one of the things you need to do. And don't have setter methods at all in that case.
Depending on the context, the use of getters and setters is actually a bigger violation of encapsulation than using member variables in constructors. If you want to set the member variable 'name' of this class, either of these approaches would work since the construction is hidden from the caller and thus not violating encapsulation. One warning is that the use of setName within the constructor might call an overrided method in a subclass which may not be what you want (since it may leave name undefined in the superclass).
Here's a similar question to yours that may provide additional insight:
calling setters from a constructor
the private variables are accessible directly anywhere in the class
settng variabels private is to encapsulate them from other classes
Setting variables to private is to encourage encapsulation from other classes.
Unless setName(String) was meant to do something extra (which the method name doesn't imply), it's unnecessary to use the setter while you're in the class where the private variable is.
This does not defeat encapsulation since the private member is still hidden from the other classes
If the modifier method does not contain any logic and just sets the member then there is no difference between directly setting the member of calling its setter method although for better practice the setter should be called.
The setter indicates that this person's name might change in the future and allows it easily without creating an entire person object again.
Initializing variables inside constructor is a very common practice. It can be used to assign values to variables based on which constructor user has called. You cannot write code based on assumption that the client code will invoke setter method to assign value to instance variables. It is always safe to assign default value to a variable when its object is created (i.e inside constructor).
There is a difference between initializing variables within constructor and setting it to different value as per requirement of the calling code(using setter method). Both have different purposes and different objectives.
This is perfectly normal. Some variables might need to be initialized as soon as the object is created, hence it makes sense to pass them in the constructor and many times we may not want to provide setters for those variables to avoid changing the values after object is created.
Its ok to directly assign values with in class provided setter doesn't do any other processing.
Basically setters/getters are used to provide restrictive access to private data such as returning copy of the data instead of reference of private object, validating data in getter etc..
Since the constructor is part of the object itself, and we are sure what we are doing is right, then its ok.
My preferred approach (as described by Joshua Bloch in "Effective Java") is to make the constructor private, make the fields final (i.e., eliminate the setters entirely), and require clients to obtain instances either using the Builder Pattern or Factory Method Pattern, which would take care of any necessary validation to protect invariants. Then the (private) constructor would simply directly assign the given parameters (which have already been validated by the Builder or Factory Method) to the appropriate fields, which are private and final.
When should I use a constructor and when should I use static method?
Can you explain above with small snippet? I skimmed through a few threads but I'm still not clear with this.
Joshua Bloch advises to favor static factory methods instead of constructors (which I think is a good practice). Couple of advantages and disadvantages :
Advantages of static factory methods :
unlike constructors, they have names
unlike constructors, they are not required to create a new object each time they're invoked (you can cache instances : e.g. Boolean.valueOf(..)
unlike constructors, they can return an object of any subtype of their return type (great flexibility)
Disadvantages of static factory methods :
They are not really distiguishable from other static methods (it's hard to find out how to initialize an object if you are not familiar with the API)
The main disadvantage (if you use only static factory methods, and make constructors private) is that you cannot subclass that class.
Use a public constructor when you only ever want to return a new object that type and you want simplicity.
A good example is StringBuilder as it's mutable and you are likely to want a new object each time.
public String toString() {
StringBuilder sb = new StringBuilder();
// append fields to the sb
return sb.toString();
}
Use a static factor method when you might want to re-use objects (esp if immutable), you might want to return a sub-class or you want descriptice construction. A good example is EnumSet which has a number of static factories which do different things even though some have the same arguments.
EnumSet.noneOf(RetentionPolicy.class);
// has the same arguments, but is not the same as
EnumSet.allOf(RetentionPolicy.class);
In this case, using a static factory makes it clear what the difference between these two ways of construction the set.
Also EnumSet can return two different implementations, one optimised for enums with a small number of values (<= 64) RegularEnumSet and another for many values called JumboEnumSet
Always use a constructor if your class has a state (even for a single instance; singleton pattern ).
Only use static for utility methods like in java.lang.Math
Example:
public static int max(int a, int b) {
return (a >= b) ? a : b;
}
Doesn't change any state (instance variables) of an object, thus it can be declared static.
Use constructor when you need an object and other stuffs like functions and variables having one copy for every object.
when you want to do something without creating object then use static method.
Example:
public class Test {
public int value;
public static int staticValue;
public int getValue() {
return ++value;
}
public static int getStaticValue() {
return ++staticValue;
}
}
public class TestClass {
public static void main(String[] args) {
Test obj = new Test();
Test obj1 = new Test();
S.o.p(obj.getValue());
S.o.p(obj1.getValue));
S.o.p(Test.getStaticValue());
S.o.p(Test.getStaticValue());
}
}
Static factory methods have names, constructors don't. Thus factory methods can carry natural documentation about what they do that constructors can't. For example, see the factory methods in the Guava Libraries, like ImmutableMap.copyOf(otherMap). While this might have little effect on behaviour of construction, it has a huge effect on readability of the code. Definitely consider this if you're publishing an API.
Also you can use a factory when you need to do any more complicated configuration of the object you're creating, especially if you need to publish to other threads (registering in pools, exposing as an MBean, all manner of other things...) to avoid racy publication. (See e.g. Java Concurrency In Practice section 3.2)
Static methods that do something (e.g. Math.min) are not really the same thing as static factories, which can be considered direct replacements for constructors, with added flexibility, evolvability and (often) clarity.
Whenever you need to create an instance of an object you will have to use the constructor.
So, if you want to create a Car object, then you will need a constructor for that.
The keyword static means, that your method can be called without creating an instance.
class Car
{
private int num_of_seats;
public Car(int number_of_seats)
{
this.num_of_seats = number_of_seats;
}
// You want to get the name of the class that has to do with
// this class, but it's not bounded with any data of the class
// itself. So you don't need any instance of the class, and
// you can declare it as static.
static String getClassName()
{
return "[Car]";
}
}
In general you will use static class with data that are not correlated with the instance of the object.
Another example is:
class Ring
{
private List nodes;
public Ring(List nodes)
{
this.nodes = nodes;
}
// You want to calculate the distance of two ids on the ring, but
// you don't care about the ring. You care only about the ids.
// However, this functionality logical falls into the notion of
// the ring, that's why you put it here and you can declare it
// as static. That way you don't have to manage the instance of
// ring.
static double calculateDistance(int id_1, int id_2)
{
return (id_1 - id_2)/383; // The divisor is just random just like the calculation.
}
}
As the posts above say, it's just a matter of what you want to do and how you want to do it. Also, don't try to understand everything rightaway, write some code then try different approaches of that code and try to understand what your code does. Examples are good, but you need to write and then understand what you did. I think it's the only way you will figure out
why you do staff the way you have to do.
Static methods do not have to instantiate new objects everytime. Since object instantiation is expensive it allows instances to be cached within the object. So, it can improve performance.
This is the explanation from the Effective Java :
This allows immutable classes (Item 15) to use preconstructed
instances, or to cache instances as they’re constructed, and dispense
them repeatedly to avoid creating unnecessary duplicate objects. The
Boolean.valueOf(boolean) method illustrates this technique: it never
creates an object. This technique is similar to the Flyweight pattern
[Gamma95, p. 195]. It can greatly improve performance if equivalent
objects are requested often, especially if they are expensive to
create.
i.e. if you want to use a singleton, which means that you have only one instance of the object, which might be shared with others, then you need a static method, which will internally will call the constructor. So, every time someone wants an instance of that object you will return always the same, thus you will consume memory only for one. You always need a constructor in object oriented programming, in every OO language. In java an in many other languages the default constructor of an object is implied, and built automatically. But you need some custom functionality you have to make your own.
Above you see a few good examples of the usage. However, if you have something specific in your mind, please let us know. I mean if you have a specific case where you are not sure if you should use a static method or a constructor. Anyhow, you will definitely need a constructor, but I am not sure about the static method.
Say I have some class:
public class A {
private int val = 0;
public int getVal() {
return val;
}
public void addFrom(A otherA) {
this.val += otherA.val;
if (otherA.val > 0)
otherA.val = 0;
else
otherA = Math.abs(otherA.val);
}
}
Should I be using getter methods instead to use otherA's val variable? Is it better style to do so?
Edit: This is a very simplified version of a class that takes much too long to read. But assume that there IS lazy initialization going on, that there are other methods that access this class, etc. I have updated the example method so that this may be more clear, but I hope it is clear that my question involves accessing the other object's variables, and want to know if it is faux pas to use a direct variable access for something that is not "this".
No, absolutely not.
You should use the variable directly when you're inside the class' members, and use getters in every other situation (when you would get an error because val is private anyway).
public int getVal() is intended to present your gift(variable) within a box to the outside world (encapsulation). Do you give gifts yourself in a box? It's weird, so use the variable as it is.
You can use variables, but the current code does not compile. Probably, the return should be int instead of boolean.
Probably, your intention is to override the compareTo method from the Comparable interface
Adding an unnecessary getter reveals internal structure and this is an opportunity for increased coupling.
A truly well-encapsulated class has no setters and preferably no getters either. Rather than asking a class for some data and then compute something with it, the class should be responsible to compute something with its data and then return the result.
Use of accessors to restrict direct access to field variable is preferred over the use of public fields, however, making getters and setter for each and every field is overkill. It also depends on the situation though, sometimes you just want a dumb data object. Accessors should be added for field where they're really required. A class should expose larger behavior which happens to use its state, rather than a repository of state to be manipulated by other classes.
Despite Java tutorials, Wikipedia searches, stackoverflow trolling, and hours of reading code samples, constructors still confuse the crap out of me. I've got three related questions that I've been trying to answer to help ME understand constructors a little better.
First, I've been under the impression that constructors need to be named the same as their classes. Consider:
public class Money {
public Money(long l) {
this.value = l;
}
public Money(String s) {
this.value = toLong(s);
}
public long getLong() {
return this.value;
}
public String getString() {
return toString(this.value);
}
}
I see this as four constructors...correct? So it appears that constructors not named the same as the class which contains them allowable. Can someone confirm that?
Second, I seem to have a block against understanding the set and get methods. Consider:
public class GetSetSample {
public int getFoo() {
return int Foo;
}
public void setFoo(int fooValue) {
int Foo = fooValue;
}
}
Why can't I just do this:
public class getFoo(int fooValue){
foo=fooValue;
}
and use foo = getFoo(12) from some other class/method?
The third question is a little more esoteric, but will help me conceive of the bigger picture...which is my learning style, and conducive to my ability to trace program flow when debugging. The get and set methods suggest a "to" and "from" relationship to me. e.g., Passing a value "to" a constructor, receiving the result "from" the get method. It seems to me though that the "to" and "from" will change depending on your perspective. I think that any setMethod is setting parameters for an object, even though the variable comes FROM another class or method, and the GetMethod is getting the resulting object (say, this.foo) with the appropriately set parameter. No matter where the get or set is used, in a main method or a standalone class with a single constructor, 'set' is always associated with sending a parameter and get is always associated with receiving an object with that parameter. Is that a good understanding? or am I missing a vital part?
Question 1:
I see this as four constructors...correct?
No, that class has two constructors and two methods. (getLong and getString are the methods.)
Question 2:
Why can't I just do this:
public class getFoo(int fooValue){
foo=fooValue;
}
Well, that's trying to declare a class with parameters, and also you're setting a value in a get method, which would be extremely weird. It's not clear what you're trying to achieve here, but that code is thoroughly invalid.
Question 3:
The get and set methods suggest a "to" and "from" relationship to me.
Well it's not really a relationship IMO. A relationship suggests something longer term than either of these methods. A setter typically changes the state of an object in some way, and a getter typically just returns some aspect of the state of an object. It's not really clear what the rest of your explanation meant, because you're playing somewhat fast and loose with terminology. For example: "get is always associated with receiving an object with that parameter" doesn't really make sense to me. Objects don't have parameters, methods/constructors do - and getters can fetch primitive values or references...
I suspect you would benefit from reading the "Classes" part of the Java tutorial, which talks about constructors and methods.
Regarding the first answer, there's only 2 constructors. The difference is on how they are going to be called (called using a string will use the construction having a string has a parameter and called using a long will use the other one). So to answer, yes a constructor has the same name as the class.
The two constructors :
public Money(long l) {
this.value = l;
}
public Money(String s) {
this.value = toLong(s);
}
Regarding the second answer, getters ans setters are not meant to be classes. They are supposed to be within the class itself.
Consider this example which uses getter and setters to get ans set value for the printer class :
public class Printer {
#Inject #Informal Greeting greeting;
private String name;
private String salutation;
public void createSalutation() {
this.salutation = greeting.greet(name);
}
public String getSalutation() {
return salutation;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
A good read of this link could definitly help you out !
Java oriented-object principles
You've shown 2 constructors, which do need to have the same name as the class.
You've also shown two "getter" methods, which return the value of the class variable in the form requested by the user. You can also create "setter" methods, which are used to transfer values into class variables.
You use a constructor to create an object of a particular class, and optionally to set some or all of its internal state (that is, its member variables).
You use setters and getters to isolate the class variables from the outside world, so you don't need to allow other code to access them directly. Why? Because, before a setter updates a variable, it can verify that the new value is valid, and that the operation doesn't violate any or the rules (the "business logic") that are required for the class to work properly.
So you could add a setter and update the constructor to use it:
public Money(long l) {
setValue(l);
}
public Money(String s) {
setValue(toLong(s));
}
// Example setter that validates `l` by prohibiting negative values
public Money setValue(long l) {
if (l < 0) {
// Warn about negative values
}
this.value = l;
return this; // Return the current object to allow chaining; see below.
}
Note that a setter usually doesn't need to return a value (that is, it can be type void), but it's often helpful to return the object itself. That allows you to write code like this:
Money earnings = new Money().setValue(4).setOtherField("foo");
This creates an object of type Money, sets various attributes, and stores it in the variable earnings. Clearly, this isn't terribly useful for a simple class like this, but it can be very helpful for more complex classes:
Paycheck check = new Paycheck("MyCompany")
.setEmployee("YourName")
.setSalary(50,000)
.setPaySchedule(Schedule.BIWEEKLY)
.setAccountNumber("1234567")
.setDefaultTaxRate();
I would like to try to answer your implied conceptual questions -- you've already got plenty of examples of this and that, so I'm just going to try to explain. I have no doubt you have heard most of this -- maybe all of this -- before, but am not sure and not sure which parts.
Object-oriented programming centers mostly around objects; an object is an amalgamation of code and data. You define objects by writing a class, and you create one or more copies of the object defined by that class with the class constructor (called instantiating the class).
A parallel in other languages: you can have a data structure of related items and a set of subroutines that operate on that data structure. Think of a class as a way of collecting the items in that data structure and the subroutines that operate on it into one unit.
After you have invoked a constructor, you have a copy of the data defined in that class and a way to refer to that copy. By referring to that instance when you invoke a class method, you operate on that copy of the data with the methods defined in that class.
If you were to do this in a non-OO language, you could have a routine that created a copy of the data structure in memory and then only use the methods prescribed for it on that data structure. You could have a pointer to the copy in memory and pass that pointer as a parameter to every subroutine that operated on it, and in fact that's the way some pre-OO systems were programmed.
A constructor is similar to a method call that returns a value; it involves (or can involve) the execution of statements, and it always returns an object of that class. There are also differences between a constructor and a method; until the constructor completes, for instance, the object is not fully created and shouldn't have some methods invoked on it.
So I hope that helped; if there are conceptual things you still have questions about, perhaps something in here will help you form a specific question so we can explain things further.
Many people have found that if they have spent years learning languages such as COBOL and FORTRAN then changing to OO programming involves unlearning the old languages. I certainly found this when I first tackled C++ 20 years ago. From your description you are clearly struggling with the concepts and I sympathize.
I don't think there is a simple recipe. Practice at the simple examples and don't be disheartened. Don't be afraid to ask on SO - if the questions are clearly asked you will get a useful answer.
Get a good IDE (Eclipse, Netbeans, etc.) which allows you to "look inside" objects with the debugger. Hopefully at some stage things will click!
Question 1 - Basic Java Classes:
There's pretty much only 3 things you're going to find in a Java class
Field/attribute (Depending on your language of origin)
Method
Constructor (Which looks like a special kind of method)
Every class is going to have a class name that shares the name of the file it's located in. So to expand Money out a bit:
Money.java
----------
public class Money {
// This is a field/attribute
Long value;
// This is a constructor
public Money() {
this.value = Long(0L);
}
// This is a method
public Long getValue() {
return value;
}
// Another method
public void makeMoney(Long moreMoney) {
this.value = this.value + moreMoney;
}
} // Everything in here is part of the Money class
The only distinction between a constructor and a method is that a constructor has no specified return value, which is declared as a type right before the name of a potential method. Constructors do have to be named the same as the class they are contained in, but why is implied in how they are written.
Another way of looking at it is if you remove all of the non-type related Java keywords (public, private etc., but not things like float and int) from the front of the method you're looking at (A list of which you can find here), is there anything left in front of the method?
With the Money we have at the moment, it would look like this:
Money()
Long getValue()
void makeMoney()
The constructor is the one that has no type for the return value, because it is implied in the declaration.
Question 2/3 - Get/Set methods:
I'm going to say something potentially controversial, but don't worry about these yet. Get/Set are essentially patterns for Object Oriented development, and generally good Java style, but they aren't required (Last I checked, Android development actually discourages their use when possible for optimization reasons). Moreover, not all fields in your objects will be accessible or mutable so writing them isn't mandatory.
If you declare all of your fields as public (Like the 'value' field is implied to be right now), you simple can do this:
Money myMoney = new Money(new Long(40L));
System.out.println(myMoney.value) // 40
myMoney.value = new Long(20L);
System.out.println(myMoney.value) // 20
Aside from that, the notion of get() and set() are just methods. There is nothing special about them at all. The main reason they exist is because for general Object-Oriented programming, you shouldn't have to directly modify the internal workings of an object (This is the principle of Encapsulation). Everything you should need to affect state or get something out of it should be handled by a method.
In a pithy one-liner: If you need to know the fields of an object to use it, you designed it incorrectly.
Big Picture
So what get() and set() really are is a pair of commonly written methods that happen to affect a field in an object in an extremely simple way (get() is a simple access to a field, set() is assignment to that field). It's just that other methods you write will happen to do more complicated stuff than that.
My professor really emphasizes protecting against privacy leaks by always using accessors and mutators to access private instance variables; however, do I have to use the getters/setters of a class within the class?
So for instance, if I have the following class:
public class Person
{
private String name;
private int age;
}
and I want to write a toString() method for it. Can I just write:
public String toString()
{
return name + " " + age;
}
OR do I need to do something like this:
public String toString()
{
return this.getName() + " " + this.getAge();
}
You CAN do either one. However, your professor might appreciate using the methods instead of the direct access. Here's why.
Let's say you have a class like this:
class SomeClass {
private int someValue;
private String someString;
public SomeClass(int someValue, String someString) {
this.someValue = someValue;
this.someString = someString;
}
public int someValue() {
return this.someValue;
}
public String someString() {
return this.someString;
}
public String toString() {
return someValue + ": " + someString;
}
}
It's pretty straightforward, right? Well, what if all of a sudden we want to CHANGE the implementation of how we calculate someValue, and base it off of someString:
public int someValue() {
int value = 0;
for(int i = 0; i < someString.length; i++) {
if(someString.charAt(i) == ' ') value++;
}
return value;
}
Now you also have to change every place where variable someValue was used.
So if you want to make the code easier to maintain in the long run, use the methods calls. This way when you code changes on you (and trust me, it changes all the time) you only have to change it in one spot instead of two.
And yes, you would want to use a method call in getting someString instead of the direct access in the last method :-)
When I design a class I try to make a clear distinction between the inside (implementation details) and the outside (the interface exposed to the world). Getters and setters provide a convenient place to convert values between the form in which they are stored in the object’s instance members and the form in which the outside world sees them. Using getters and setters internally would muck that up, because they'd be getting used by both the inside and outside.
If you find yourself wanting to hide part of a class from another part of the same class, consider breaking off the part you want to hide into its own class.
It's normally not a good idea, for a number of reasons:
You may not even want accessors for all fields
Some accessors may make a defensive copy so not to expose internal state, this is normally unnecessary within the class where you know that you are not going to modify it - or plain wrong if you know you ARE going to modify it
It makes debugging more annoying, because you have to follow the getters / setters
It makes reading the code harder in most IDEs, since most of them color fields differently than local variables
... but as always, there are exceptions. Some setters may have side-effects (for example setting a second value) that you WANT to execute, then it might be better to use the setter. Also, if you design your class for inheritance, it may be better to go via an accessor if you want the subclass to be able to alter the behavior.
In general, no. If your getter returns something other than the value of the field then you should use the method, but in that rare case your method should have a more descriptive name. For a bad example, if you have:
public void setName(String name)
{
_name = name;
}
and your getter returned something else, like
public String getName()
{
return _name.toUpperCase();
}
then yes, you should use the getter. It would be better, though, to have a more descriptive name for that getter:
public String getNameAsUppercase()
{
return _name.toUpperCase();
}
You can use the accessors and mutators, but its a messy standard to follow.
It clutters up your code and confuses anyone trying to read it thinking it might not be a part of your class.
Basically, just access the variables directly from inside your class, and indirectly from anywhere else.
On the flip side, consider it from a design standpoint. One of the motivations for getters/setters is that the underlying data storage can change and things that implement the class won't need to be changed since it is encapsulated.
So, keeping that in mind, using getters/setters within the class makes future changes easier. Instead of having to find all the places that alter the member directly, you just have to change the getter/setter. Depending on the complexity of the class, this may significantly reduce the amount of work it takes to change the storage members.
For example, let's assume you start out with the age variable in years. Then you decide later to store it as seconds for some reason. But you want to always print it in years anyway. So in your example, you could do the math in your toString() function (and anywhere else that wants years as the units) or you can just change the math in the getAge() routine to return years from the seconds and nothing else has to change.
Obviously that example is a bit trivial. The more complicated the class, the more useful it is to use getters/setters within it.
No, you don't. You can access any variables, private, public or protected, from within the class.
Here are some tables to help you:
Source: Java Tutorials
If your class (or the accessor methods in question) is not final, then you should definitely use the accessor methods.
If another class extends yours and overrides those accessors, your class should use the overridden accessors. If this would break your superclass, then your superclass is designed incorrectly; prevent those accessors from being overridden with final, or change the design of your class.
No you can use directly your instance variables inside the class, you're not violating any "rule". Getters and setters are mandatory for others classes to access instance variables of a class to not violate the encapsulation principle (which is quite important in OO programming).
In the end it's a matter of choice, but you're saving one method call using your first example.
I think we should use getters() and setters() instead of accessing directly. It is also makes debugging very easy; for example, if you need to assign a variable to multiple place in your class and later want to find out from how many places the variable is assigned to, then you need to find all the assignment and set the break point.
However, if you use a setter you can simply put a break point inside the setter method and can see how many time the variable is assigned.
I use a mix of both. Accessor methods add more clutter so I use them only when the variable is used many times. If the variable is used only once or twice I don't use them.