Skip to main content

Java Classes

The Aims​

This lab will introduce you to defining classes with instance methods and variables, and then instantiating and manipulating the resulting objects from a main method.

Defining a class​

We are going to create a new class called Account, and save it in a file called Account.java.

  1. In your preferred editor, create a new class called Account.

  2. Provide two properties called balance and name, setting them to be a double and a String respectively. These variables should be declared as private.

  3. Now provide methods which will set and return the balance and the name. Ie. Provide, get and set methods for your two variables. You can use the IDE's Generate Getters and Setters function if you wish.

  4. Define a new method called addInterest, which does not take in any parameters or return any value, but increases the balance by 10%. We will be using this method later.

  5. Check for any errors before proceeding.

Click here to see the sample solution

public class Account {
private double balance;
private String name;

public double getBalance() {
return balance;
}
public void setBalance(double balance) {
this.balance = balance;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}

public void addInterest() {
balance *= 1.1;
}
}

Instantiating the class​

  1. Create another class called TestAccount and this time add a main method to it. You can do this at the New Class dialog or in the blank class, type the word psvm (if using IntelliJ) or main (if using VSCode), and the press the tab key.

  2. Within this main method, declare and instantiate a new Account object called myAccount, and then call the set methods to give it a name and a balance. Set name to be your name, and you can give yourself as much money as you like!

  3. Now print out the name and balance to the screen using the get methods. Place appropriate text before the values using the string concatenator (+).

  4. Fix any errors, and run your program. It should print out your name and balance variables.

  5. Call the addInterest method and print out the balance again. It should be different when you run it.

Click here to see the sample solution

public class TestAccount {
public static void main(String[] args) {
Account myAccount = new Account();
myAccount.setName("John Doe");
myAccount.setBalance(1000.0);

System.out.println("Account Name: " + myAccount.getName());
System.out.println("Initial Balance: " + myAccount.getBalance());

myAccount.addInterest();

System.out.println("Balance after interest: " + myAccount.getBalance());
}
}

Adding Constructors​

We will now add a constructor to our Account class so that we can create accounts and give them a value for the name and balance variable upon instantiation.

  1. In your Account class, define a constructor that takes a String and a double. Assign those values to your instance variables name and balance.

  2. In your Account class, define a no argument constructor that passes your first name and a balance of 50 to the constructor taking a String and a double. Remember, this is done using the this keyword. You will not need this constructor for rest of the exercise, but it is useful to see how it can be done.

  3. Now create a new class called TestAccount2 that has a main method.

  4. In the main method, create an array of 5 account objects. Set the name and balance when you create each account object. To do this, use the constructor you added that takes in a name and a balance.

Click here to see the sample solution

public class Account {

...

public Account(double balance, String name) {
this.balance = balance;
this.name = name;
}

public Account() {
this.balance = 50;
this.name = "John";
}

...
}
public class TestAccount2 {
public static void main(String[] args) {
Account[] accounts = new Account[5];
accounts[0] = new Account(1000.0, "Alice");
accounts[1] = new Account(2000.0, "Bob");
accounts[2] = new Account(1500.0, "Charlie");
accounts[3] = new Account(3000.0, "Diana");
accounts[4] = new Account(2500.0, "Eve");
}
}

Static variables and methods​

So far, the interest rate for our account object is somewhat arbitrarily defined by our addInterest method. We will now create a variable, which will be the interest rate for our Account objects. This will be a static variable – why?

  1. In the Account class, declare and initialise a static variable of type double to be the interest rate for the Account class. Call it interestRate. Also, provide a set and get method for the variable - remember that these will be static methods.

  2. Modify the addInterest instance method to use this variable instead of our fixed value.

  3. From your main method, change the interest rate using the Account class static method Account.setInterestRate(someDouble) that you defined earlier in step 5.

  4. In the TestAccount2 main method, loop though your array. In the loop you should:

    1. Display the balance
    2. Call the addInterest method
    3. Display the new balance
  5. Run your class. Is it using your new interest rate value?

Click here to see the sample solution

public class Account {

...

private static double interestRate = 0.1;

public static double getInterestRate() {
return interestRate;
}

public static void setInterestRate(double interestRate) {
Account.interestRate = interestRate;
}

...

public void addInterest() {
balance *= (1+interestRate);
}
}
public class TestAccount2 {
public static void main(String[] args) {
Account[] accounts = new Account[5];
accounts[0] = new Account(1000.0, "Alice");
accounts[1] = new Account(2000.0, "Bob");
accounts[2] = new Account(1500.0, "Charlie");
accounts[3] = new Account(3000.0, "Diana");
accounts[4] = new Account(2500.0, "Eve");

Account.setInterestRate(0.07);

for (int i = 0; i < accounts.length; i++) {
System.out.println("Account Name: " + accounts[i].getName());
System.out.println("Initial Balance: " + accounts[i].getBalance());
accounts[i].addInterest();
System.out.println("Balance after interest: " + accounts[i].getBalance());
System.out.println();
}
}
}

Method Overloading​

Finally, we will put in some method overloading. We will provide two methods with the same name that take in different arguments. Our methods will both be called withdraw. One will take in a parameter called amount, and the other will not require a parameter.

  1. In the Account class, define a withdraw method that takes in a value and checks that there is enough money in the account and if there is, the balance is reduced by the amount passed in. The signature will be:

public boolean withdraw(double amount)

This method will return a boolean, true if there was enough money and false if there was not.

  1. Now define a second withdraw method. This takes in no parameters, and deducts an arbitary value of 20 from the account. This also should return a boolean, true if there is enough money, and false if not, as before.

HINT: Is there a way to write this method in a way that does not duplicate the code you created in the previous step.

  1. Now in your test class, try calling withdraw on some of your account objects. Make calls to both methods, passing in values that are higher than the balance, and check that it doesn’t let you draw the money out (ie. Returns false).

  2. You could modify your withdraw methods to also display a message on the screen as well as return true or false, so your users know whether it has been a successful transaction or not.

Click here to see the sample solution

public class Account {

...

public boolean withdraw(double amount) {
if (amount <= balance) {
balance -= amount;
System.out.println(name + " now has a balance of " + balance);
return true;
} else {
System.out.println(name + " has insufficient funds for this withdrawal");
return false;
}
}

public boolean withdraw() {
return withdraw(20);
}

...
}

public class TestAccount2 {
public static void main(String[] args) {

...

accounts[0].withdraw(100);
accounts[1].withdraw();
accounts[2].withdraw(2500);
}
}