• Tidak ada hasil yang ditemukan

Bad Ver sion

Step 4 Development: Finishing Up

4.5 Constructors

Consider the following code:

Account acct;

acct = new Account( );

acct.setInitialBalance(500);

acct.setInitialBalance(300);

What is the effect of such code? It is logically inconsistent to initialize the starting balance more than once. It should be called exactly one, but there is no such Java language feature that puts constraints on the number of times the setInitialBalance method can be called. The existence of this method is a problem, and we can remove it from the Accountclass by defining a constructor that sets the initial balance to a specified amount.

Now consider the following code:

Account acct;

acct = new Account( );

acct.add(200.00);

If an account can have the initial balance of zero, this code is acceptable. But if there is a rule that says, for example, an account must have the initial balance of $25 or more, then thesetInitialBalancemethod must be called first to initialize the balance to 25.00 or more before any transactions (addordeduct) take place. This problem can also be solved by the same constructor that sets the initial balance to a specified amount.

Here’s a new constructor that eliminates the two problems in one stroke:

public Account(double startingBalance) { ownerName = "Unassigned";

balance = startingBalance;

}

Once this constructor is defined, there is no longer a need for the setInitialBalance method, so we can safely remove it from the class defintion. Only the add and deductmethods affect the balance after an object is created.

After the old constructor is replaced by this new constructor, we must create an instance by passing one argument when calling the newoperator. For example, the code

Account acct;

acct = new Account(500.00);

will create a new Accountobject with its starting balance set to $500. We can no longer create an instance by writing

Account acct;

acct = new Account( );

because there is no matching constructor anymore.

Instead of this one-parameter constructor, we can define a constructor that accepts the name of the owner also, so that it, too, can be initialized at the time of object creation. Here’s how we define the two-parameter constructor:

public Account(String name, double startingBalance) { ownerName = name;

balance = startingBalance;

}

This is the constructor we will include in the modified Accountclass. With this two- parameter constructor, here’s how we create an Accountobject:

Account acct;

acct = new Account("John Smith", 500.00);

Notice that, even with this new constructor, we will keep the setOwnerName method in the class because we want to be able to change the name of the owner after the account is created.

From the three different constructors possible for the Accountclass, we have selected the two-parameter constructor to include in the class. Actually, it is possi- ble to include all three constructors in the definition of the Accountclass. But until we learn how to define multiple constructors in Chapter 7, we will define exactly one constructor for our programmer-defined classes.

It is possible to define more than one constructor to a class. Multiple contructors are called overloaded constructors. It is almost always a good idea to define multi- ple constructors to a class. But to keep things simple, we will manage with one constructor per class until Chapter 7.

class AccountVer2 { // Data Members

private String ownerName;

private double balance;

//Constructor

public AccountVer2(String name, double startingBalance) {

We are now ready to list the complete definition. Here’s the second version of the Accountclass (for the actual class name we will use AccountVer2to avoid con- fusion when discussing different versions of the class definition):

Default Constructor

As a design guideline, we strongly recommend to include constructors to programmer-defined classes, as we have been doing from the beginning of the chapter. However, it is not a requirement to define a constructor explicitly in a class. If no constructor is defined for a class, then the Java compiler will auto- matically include a default constructor. Adefault constructoris a constructor that accepts no arguments and has no statements in its body. For example, if we omit a constructor from theBicycle class, a default constructor

public Bicycle( ) { }

will be added to the class by the compiler to ensure its instances can be created.

Even though a default constructor is automatically added by the compiler, we should never rely on it. We should always define our own constructor so that we can ownerName = name;

balance = startingBalance;

}

//Adds the passed amount to the balance public void add(double amt) {

balance = balance + amt;

}

//Deducts the passed amount from the balance public void deduct(double amt) {

balance = balance - amt;

}

//Returns the current balance of this account public double getCurrentBalance( ) {

return balance;

}

//Returns the name of this account's owner public String getOwnerName( ) {

return ownerName;

}

//Assigns the name of this account's owner public void setOwnerName(String name) {

ownerName = name;

} }

default constructor

initialize the data members properly and carry out any other initialization tasks.

This ensures an object is created in a valid state (such as setting the balance of an account to more than the minimum).

Always define a constructor and initialize data members fully in the constructor so an object will be created in a valid state.

Once we define our own constructor, no default constructor is added. This means that once the constructor, such as

public Account(String name, double startingBalance ) { ownerName = name;

balance = startingBalance;

}

is added to the Accountclass, we will no longer be able to create a Accountobject anymore by executing

Account acct;

acct = new Account( );

because no matching constructor can be found in the class.

Once a programmer has added an explicitly defined constructor to a class, no default constructor will be added to the class by the compiler.

Let’s define another class for practice. We learned in a chemistry class that an element is the simplest type of matter that consists of exactly one kind of atom. These elements have unique physical and chemical properties. The elements are classified into groups and periods in the periodic table. Each element is represented by its

1. name (e. g., hydrogen, helium, lithium, etc.);

2. atomic number (e.g., 1, 2, 3, etc.);

3. atomic symbol (e.g., H, He, Li, etc.);

4. atomic mass (e.g., 1.008, 4.003, 6.941, etc.);

5. period (it ranges from 1 to 7);

6. group (it ranges from 1 to 18 under the new system).

We name the class Element. The class has one constructor and six accessors (get methods) for the six attributes. We do not have any mutators (set methods) for this class because once an Element object is created we will never change the values of its attributes. Because all of its attributes must be specified, the constructor has six parameters. Here’s the Elementclass:

class Element { //Data Members

private String name;

private int number;

private String symbol;

private double mass;

private int period;

private int group;

//Constructor

public Element (String elementName, int elementNumber, String elementSymbol, double elementMass, int elementPeriod, int elementGroup) { name = elementName;

number = elementNumber;

symbol = elementSymbol;

mass = elementMass;

period = elementPeriod;

group = elementGroup;

}

//Returns the element’s name public String getName () {

return name;

}

//Returns the element’s atomic number public int getNumber () {

return number;

}

//Returns the element’s 1- or 2-letter symbol public String getSymbol () {

return symbol;

}