If I'm guessing what you're referring to, it's just a practice of encapsulation. It's used a lot in beans. It's used to alter the value of a given object. Here's an example:
public class SpeedDemo {
private int speed = 5;
public void setSpeed(int inSpeed) {
if (inSpeed < 0) {
speed = 0;
}
else {
speed = inSpeed;
}
public int getSpeed() {
return speed;
}
}
As you can see, this basically allows you to set the "speed" variable. Instead of doing SpeedDemo.speed = value, you can make sure the rate of speed doesn't go below zero. You do error-checking instead of allowing them to directly access your class variable. That's the premise behind set/get methods.
Michael Bishop
the question then is why define a variable private if it is going to be exposed with get and set methods, just define it public!
the alternative is to pass the 'other' object into this class, and have this class interact with the other class through well known interfaces. This way, how the variable is defined and if it is changed later, will not affect the other class.
for sure that is the case. does one carry it out when using the variable in the same class? I happen to use the methods to get/set the variable even though being in the same class and it is eg an instance variable, one could do direct assignments. there are advantages both ways I suppose. when get/set is used outside of the class, it serves as a warning signal and possible refactor case.
So when I write a class and fill it with various fields, such as String name
double currentBalance
double interestRate
String dateOpened
I create 'set' methods that are void and 'get' methods that have the same return type as the field?
And where does the inSpeed variable come from? Is that a value that a user would enter?
that is right on both counts. If you had the following:
public class Test {
// define class variables
private String name;
...
public void setName(String s) {
name = s;
}
public String getName() {
return name;
}
then the user would create their own object by instantiating the class (Test t = new Test();). They can then set about "setting" and "getting" using the accessor and mutator methods provided in the class. The variables would be provided by the user i.e.
t.setName("New name");
hope that helps
ML
That's right, all they do is get the value in the variable, no parameters are required.
When you use getters and setters it is easier to track where the variable is being used by tracking where the getter and setter methods are being referenced. It is much harder to search through the code to find out where you are using a certain variable then you are directly accessing the variable.
Sorry there was a typo in my last post.Should read:
That's right, all they do is get the value in the variable, no parameters are required.
When you use getters and setters it is easier to track where the variable is being used by tracking where the getter and setter methods are being referenced. It is much harder to search through the code to find out where you are using a certain variable when you are directly accessing the variable.
What am I missing? When I import the following class into a driver class, my println statement returns "null, 0.0, $0.00, null".
The driver class is after the BankAccount class.
import java.text.NumberFormat;
public class BankAccount {
private NumberFormat fmt = NumberFormat.getCurrencyInstance();
private final double INTEREST_RATE = 0.055; //interset rate is 5.5%
private String name;
private double accountNumber;
private double currentBalance;
private String dateOpened;
public BankAccount(){}
public BankAccount(String name, double accNum, double balance, String date) {
name = name;
accNum = accountNumber;
balance = currentBalance;
date = dateOpened;
}
//--SET METHODS
public void setString(String string) {
name = string;
}
public void setAccountNumber(double number) {
accountNumber = number;
}
public void setCurrentBalance(double balance) {
currentBalance = balance;
}
public void setDateOpened(String date) {
dateOpened = date;
}
//--GET METHODS !!!NO PARAMETERS!!!
public String getString() {
return name;
}
public double getAccountNumber() {
return accountNumber;
}
public double getCurrentBalance() {
return currentBalance;
}
public String getDateOpened() {
return dateOpened;
}
public String toString() {
return (name + "\t" + accountNumber + "\t" + fmt.format(currentBalance) + "\t" + dateOpened);
}
}
import BankAccount;
public class TestBankAccount {
public static void main(String[] args) {
BankAccount acct1 = new BankAccount("Jack Frost", 4567, 123.45, "August 9, 2000");
BankAccount acct2 = new BankAccount();
BankAccount acct3 = new BankAccount();
System.out.println(acct1);
}
}
You got your constructor backwards:
// These parameters are what the user is passing in.
// You want to set your class variables to these values,
// not vice-versa.
public BankAccount(String name, double accNum, double balance, String date) {
// Since you re-use the same variable name, you
// have to specify. "this" points to this object.
this.name = name;
accountNumber = accNum;
currentBalance = balance;
dateOpened = date;
}
Make sense? Otherwise, it looks pretty good.
Michael Bishop
> the question then is why define a variable private if it is
> going to be exposed with get and set methods, just
> define it public!
(1) Because you might decide not to have a separate variable for each propety. Using private variables and get/set methods allows you to change
public class Foo {
private byte bar1, bar2, bar3, bar4;
// etc.
}
to
public class Foo {
private int barBitfield;
// etc.
}
without breaking any existing code in other classes.
(2) Because you might want your mutator method to have other side effects than just setting the varaible. The setVisible() method in the component classes is a good example.
> the question then is why define a variable private if
> it is going to be exposed with get and set methods,
> just define it public!
>
Because you have control. How could this guy ensure that speed was never set to a negative value without the logic in his set method.
Java can also use introspection to discover what properties a JavaBean has from looking at its get/set methods. You might say why not just look at the public variables? Answer: because setting a property might actually involve something more complex going on in the background (eg. a database call) that you are hiding from the user.
Learn from Smalltalk where all instance variables are private.
this example is contrived but maybe useful:
in the first two inner classes, changing from byte to Byte changes the signatures.
public class WhyGetSet
{
private class GetSetbyte
{
private byte b1;
public byte getValue()
{
return b1;
}
public void setValue( byte b )
{
b1 = b;
}
}
private class GetSetByte
{
private Byte b1;
public Object getValue()
{
return b1;
}
public void setValue( Object b )
{
b1 = (Byte)b;
}
}
private class NoGetSetCaller
{
private int val;
public NoGetSetCaller()
{
NoGetSet ngs = new NoGetSet( this );
//or
ngs.setValueFor( this );
}
public void setValue( int v )
{
this.val = v;
}
}
private class NoGetSet
{
private byte b1;
private Byte B1;
public NoGetSet( NoGetSetCaller c )
{
setValueFor( c );
}
private void setValueFor( NoGetSetCaller c )
{
int i = (int) b1;
c.setValue( i );
int I = (int) B1.byteValue();
c.setValue( I );
}
}
public WhyGetSet()
{
}
public static void main( String[] args )
{
WhyGetSet wgs = new WhyGetSet();
}
}
It's also important to note that it is standard to have your getter and setter methods match your private variable name. In your code that you pasted, I notice that you have
public void setString(String string) {
name = string;
}
This method, by the common convention, would be better named as setName, since that is actually what you're setting. Besides that, you have two String properties in your class, name and dateOpened. So how do I know which variable setString is setting?For that matter, I would expect the toString() method to return the same value I passed into setString(), but that is incorrect!
So you see, by keeping with the naming convention you make your classes easier to understand, read, and maintain. In so doing, you make something that is more reliable and reusable in the future.
--David