4 Methods & Fields

Classes, Methods, Fields, and Objects

Objective

  • Declare a class and use it to create an object.
  • Declare methods in a class to implement the class’s behavior.
  • Declare instance variables (fields) in a class.
  • Call an object’s method to make that method perform its task.
  • Differentiate between instance variables of a class and local variables of a method.
  • Use a constructor and initialize objects with constructors.
  • Distinguish between primitive types and reference types.
  • Work with overloaded constructors.

Exercise 1*

  1. Create a new project, call it bank, then add the following class to it:

    Account.java
    public class Account {
      private String name; // instance variable
     
      public String getName() {
        return name;
      }
     
      public void setName(String name) {
        this.name = name;
      }
    }
Account-name : String+getName() : String+setName() : String
  1. Create a new class called AccountTest that contains a main method. In the main method, create an object of class Account, and print the value of variable name of this object.

  2. Do we need to use import statement to import Account class? Why?

  3. Is it necessary to use the keyword this in the method setName()?

  4. What are the default values for instance variables of the following types:

    TypeValue
    int_____
    double_____
    float_____
    boolean_____
    Object_____
  5. Add a constructor that specifies custom initialization for the instance variable name and try to run AccountTest again.

  6. Which of the following statements is correct and which is not:

    1. If a class does not define constructors, the compiler provides a default constructor with no parameters.
    2. There is no default constructor in a class that declares a constructor.
    3. The class can have only one constructor.
  7. Add another instance variable called balance, and add the corresponding setter/getter methods. The setBalance() method should ensure that balance will not be negative.

  8. Add another constructor that specifies custom initialization for the variables: name, balance. The constructor should ensure that balance will not be negative.

  9. Add a method called deposit() that increases the balance. The method should ensure that the deposit amount is greater than zero.

  10. Add a method called withdraw() that withdraws money from an account. Ensure that the withdrawal amount does not exceed the account’s balance. If it does, the balance should be left unchanged and the method should print a message indicating Withdrawal amount exceeds account balance.

  11. Test these methods in the class AccountTest.

Account-name : String-balance : double+Account(String)+Account(String, double)+getName() : String+setName(String) : void+getBalance() : double+setBalance(double) : void+deposit(double) : void+withdraw(double) : void
Solution
Account.java
public class Account {
  private String name;
  private double balance;
 
  public Account(String name) { setName(name); }
 
  public Account(String name, double balance) {
    setName(name);
    setBalance(balance);
  }
 
  public String getName() { return name; }
 
  public void setName(String name) { this.name = name; }
 
  public double getBalance() { return balance; }
 
  public void setBalance(double balance) {
    if (balance >= 0.0) {
      this.balance = balance;
    }
  }
 
  public void deposit(double amount) {
    if (amount > 0.0) {
      balance += amount;
    }
  }
 
  public void withdraw(double amount) {
    if (amount > 0.0) {
      if (balance >= amount) {
        balance -= amount;
      } else {
        System.out.println("Withdrawal amount exceeded account balance.");
      }
    }
  }
}
AccountTest.java
public class AccountTest {
  public static void main(String[] args) {
    Account account1 = new Account("Dane Doe");
    Account account2 = new Account("Zane Doe", 100);
 
    System.out.println(account1.getBalance());
    System.out.println(account2.getBalance());
 
    account1.setBalance(-100);
    account1.setBalance(200);
    account1.withdraw(500);
    account1.withdraw(50);
    account2.deposit(100);
 
    System.out.println(account1.getBalance());
    System.out.println(account2.getBalance());
  }
}

Exercise 2*

Debugging

The program in this section does not compile. Fix all the compilation errors so that the program will compile successfully. Once the program compiles, execute the program, and compare its output with the sample output; then eliminate any logic errors that may exist. The sample output demonstrates what the program’s output should be once the program’s code is corrected.

Person-firstName : String-lastName : String-age : int+Person(String, String, int)+getFirstName() : String+setFirstName(String) : void+getLastName() : String+setLastName(String) : void+getAge() : int+setAge(int) : void
Person.java
// Person.java
// Creates and manipulates a person with a first name, last name and age
 
public class Person {
  private String firstName;
  private String lastName;
  private int age;
 
  public void Person(String first, String last, int years) {
    firstName = first;
    lastName = last;
    if (years < 0)
      age = years;
  } // end Person constructor
 
  public String getFirstName(String FirstName) {
    return firstName;
  } // end method getFirstName
 
  public setFirstName(String first) {
    firstName = first;
  } // end method setFirstName
 
  public String getLastName() {
    return;
  } // end method getLastName
 
  public void setLastName(String last) {
    lastName = last;
  } // end method setLastName
 
  public int getAge() {
    return years;
  } // end method getAge
 
  public void setAge(int years) {
    if (years > 0)
      age = years;
  } // end method setAge
} // end class Person
PersonTest.java
// PersonTest.java
// Test application for the Person class
 
public class PersonTest {
  public static void main(String[] args) {
    Person person = Person("Dane", "Doe", 19);
 
    System.out.printf("Created %s %s, age %d%n", getFirstName(), getLastName(),
                      getAge());
    person.setAge = person.getAge() + 1;
    System.out.printf("Happy birthday to %s %s!%n", person.getFirstName(),
                      person.getLastName());
  } // end method main
} // end class PersonTest
Created Dane Doe, age 19
Happy birthday to Dane Doe!

Exercise 3*

Constructor Overloading

The following two classes represent the solution to Exercise 2. You can use your own solution of that exercise and update the small changes in PersonTest.java to display the updated age. Otherwise, create a new project and add to it the following two classes, then answer the questions given below:

Person.java
public class Person {
  private String firstName;
  private String lastName;
  private int age;
 
  public Person(String firstName, String lastName, int age) {
    setFirstName(firstName);
    setLastName(lastName);
    setAge(age);
  } // end Person constructor
 
  public String getFirstName() {
    return firstName;
  } // end method getFirstName
 
  public void setFirstName(String first) {
    firstName = first;
  } // end method setFirstName
 
  public String getLastName() {
    return lastName;
  } // end method getLastName
 
  public void setLastName(String last) {
    lastName = last;
  } // end method setLastName
 
  public int getAge() {
    return age;
  } // end method getAge
 
  public void setAge(int years) {
    if (years > 0) {
      age = years;
    }
  } // end method setAge
} // end class Person
PersonTest.java
public class PersonTest {
  public static void main(String[] args) {
    Person person = new Person("Dane", "Doe", 19);
 
    System.out.printf("Created %s %s, age %d%n", person.getFirstName(),
                      person.getLastName(), person.getAge());
 
    person.setAge(person.getAge() + 1);
    System.out.printf("Happy birthday to %s %s%nYour age is now %d%n",
                      person.getFirstName(), person.getLastName(),
                      person.getAge());
  } // end main
} // end class PersonTest
  1. Run PersonTest.java and make sure that your output is similar to:

    Created Dane Doe, age 19
    Happy birthday to Dane Doe
    Your age is now 20
  2. Now add to the Person class, two double fields representing the person’s weight and height, and generate setters and getters for both fields. This can be done automatically using your IDE.

    • IDEA: Press N (macOS) or Alt+Insert (Windows/Linux) for the Generate menu then select Getter and Setter.
    • Code: Right-click or open the Command Palette, using P (macOS) or Ctrl+Shift+P (Windows/Linux), then select Source ActionGenerate Getters and Setters.
    • Eclipse: Select SourceGenerate Getters and Setters.
  3. Add a five-parameter constructor that initializes all the fields to the values passed as parameters. Let your new constructor call the existing constructor to initialize the first three fields; use this().

    Now the class has two constructors: what is the name of the object-oriented programming concept that allows more than one method to have the same name?

  4. Add an instance method called getBMI() to return the BMI (body-mass index) for a Person. The formula for BMI is massheight2\frac{\text{mass}}{\text{height}^2}. Make sure that the method works only for positive values of weight and height, otherwise it returns 0.0.

  5. In the PersonTest class, create a new Person instance using the 5-parameter constructor and your own information. Let the program print the new person details, together with the BMI value. Print a message saying Overweight if the BMI for the person is more than or equal 25, otherwise print Healthy.

Person-firstName : String-lastName : String-age : int-weight : double-height : double+Person(String, String, int)+Person(String, String, int, double, double)+getFirstName() : String+setFirstName(String) : void+getLastName() : String+setLastName(String) : void+getAge() : int+setAge(int) : void+getHeight() : double+setHeight(double) : void+getWeight() : double+setWeight(double) : void+getBMI() : double
Solution
Person.java
public class Person {
  private String firstName;
  private String lastName;
  private int age;
  private double weight;
  private double height;
 
  public Person(String firstName, String lastName, int age) {
    setFirstName(firstName);
    setLastName(lastName);
    setAge(age);
  }
 
  public Person(String firstName, String lastName, int age, double weight,
                double height) {
    // this.firstName = firstName;
    // this.lastName = lastName;
    // this.age = age;
    // this.weight = weight;
    // this.height = height;
 
    this(firstName, lastName, age);
    setWeight(weight);
    setHeight(height);
  }
 
  public String getFirstName() { return firstName; }
 
  public void setFirstName(String first) {
    firstName = first;
  } // end method setFirstName
 
  public String getLastName() { return lastName; }
 
  public void setLastName(String last) { lastName = last; }
 
  public int getAge() { return age; }
 
  public void setAge(int years) {
    if (years > 0) {
      age = years;
    }
  }
 
  public double getWeight() { return weight; }
 
  public void setWeight(double weight) {
    if (weight > 0.0) {
      this.weight = weight;
    }
  }
 
  public double getHeight() { return height; }
 
  public void setHeight(double height) {
    if (height > 0.0) {
      this.height = height;
    }
  }
 
  public double getBMI() {
    if (weight > 0.0 && height > 0.0) {
      return weight / (height * height);
    } else {
      return 0.0;
    }
  }
}
PersonTest.java
public class PersonTest {
  public static void main(String[] args) {
    Person person = new Person("Dane", "Doe", 19);
 
    System.out.printf("Created %s %s, age %d%n", person.getFirstName(),
                      person.getLastName(), person.getAge());
 
    person.setAge(person.getAge() + 1);
    System.out.printf("Happy birthday to %s %s%nYour age is now %d%n",
                      person.getFirstName(), person.getLastName(),
                      person.getAge());
 
    Person me = new Person("Xane", "Doe", 21, 72, 1.55);
    System.out.printf("Created %s %s, age %d, weight %.2f kg, height %.2f m%n",
                      me.getFirstName(), me.getLastName(), me.getAge(),
                      me.getWeight(), me.getHeight());
 
    if (me.getBMI() >= 25) {
      System.out.println("Overweight");
    } else {
      System.out.println("Healthy");
    }
  }
}

Exercise 4

GradeBook Application

  1. Create a new project and add the following two classes by creating the corresponding sources files under the source directory:

    GradeBook.java
    // GradeBook class with a constructor to initialize the course name.
     
    public class GradeBook {
      private String courseName; // course name for this GradeBook
     
      /* write code to declare a second String instance variable */
     
      // constructor initializes courseName with String supplied as argument
      public GradeBook(String name) {
        courseName = name; // initializes courseName
      } // end constructor
     
      // method to retrieve the course name
      public String getCourseName() {
        return courseName;
      } // end method getCourseName
     
      // method to set the course name
      public void setCourseName(String name) {
        courseName = name; // store the course name
      } // end method setCourseName
     
      /* write code to declare a get and a set method for the instructor's name */
     
      // display a welcome message to the GradeBook user
      public void displayMessage() {
        // this statement calls getCourseName to get the
        // name of the course this GradeBook represents
        System.out.printf(
            "Welcome to the grade book for%n%s!%n",
            getCourseName());
     
        /* write code to output the instructor's name */
     
      } // end method displayMessage
    } // end class GradeBook
    GradeBookTest.java
    public class GradeBookTest {
      // main method begins program execution
      public static void main(String[] args) {
        // create GradeBook object
        GradeBook gradeBook1 = new GradeBook("CMPS 251 OOP");
     
        gradeBook1.displayMessage(); // display welcome message
     
        /* write code to change the instructor's name and output changes */
     
      } // end main
    } // end class GradeBookTest
GradeBook-courseName : String+GradeBook(String)+getCourseName() : String+setCourseName(String) : void+displayMessage() : void
  1. Run the GradeBookTest application to verify that your classes are copied and work correctly.

  2. Perform the following on the GradeBook class:

    1. Declare a String instance variable to represent the instructor’s name.
    2. Declare a public set() method for the instructor’s name that does not return a value and takes a String as a parameter. In the body of the set() method, assign the parameter’s value to the variable that represents the instructor’s name.
    3. Declare a public get() method that returns a String and takes no parameters. This method should return the instructor’s name.
    4. Modify the constructor to take two String parameters. Assign the parameter that represents the instructor’s name to the appropriate instance variable.
    5. Add a System.out.printf() statement to method displayMessage() to output the value of the instance variable you declared earlier.
GradeBook-courseName : String-instructorName : String+GradeBook(String, String)+getCourseName() : String+setCourseName(String) : void+getInstructorName() : String+setInstructorName(String) : void+displayMessage() : void
  1. Perform the following on the GradeBookTest class:
    1. Add your name as the instructor for the CMPS 251 course and display.
    2. Immediately after the call to displayMessage(), output a message saying Changing course instructor:
    3. Using a setter, set the course instructor to be your friend’s name.
    4. Call the displayMessage() again to reflect the changes.
    5. Create a new GradeBook object for the course CMPS 251 OOP and make the instructor the actual current instructor of your section. Display the new course information.
Solution
GradeBook.java
public class GradeBook {
  private String courseName;
  private String instructorName;
 
  public GradeBook(String courseName, String instructorName) {
    this.courseName = courseName;
    this.instructorName = instructorName;
  }
 
  public String getCourseName() { return courseName; }
 
  public void setCourseName(String name) { courseName = name; }
 
  public void displayMessage() {
    System.out.printf("Welcome to the grade book for%n%s%nby %s!%n",
                      getCourseName(), getInstructorName());
  }
 
  public String getInstructorName() { return instructorName; }
 
  public void setInstructorName(String instructorName) {
    this.instructorName = instructorName;
  }
}
GradeBookTest.java
public class GradeBookTest {
  public static void main(String[] args) {
    GradeBook gradeBook1 = new GradeBook("CMPS 251 OOP", "Dane Doe");
 
    gradeBook1.displayMessage();
 
    System.out.println("Changing course instructor:");
 
    gradeBook1.setInstructorName("Zane Doe");
    gradeBook1.displayMessage();
  }
}

Exercise 5+

Employee Application

Create a class called Employee that includes three pieces of information as instance variables:

  • a first name of type String,
  • a last name of type String, and
  • a monthly salary of type double.

Your class should have a constructor that initializes the three instance variables. Provide a set() and a get() method for each instance variable. If the monthly salary is not positive, set it to 0.0.

Employee-firstName : String-lastName : String-salary : double+Person(String, String, double)+getFirstName() : String+setFirstName(String) : void+getLastName() : String+setLastName(String) : void+getSalary() : double+setSalary(double) : void

Create a test application named EmployeeTest that demonstrates class Employee’s capabilities. Create two Employee objects and display the yearly salary for each Employee. Then give each Employee a 10% raise and display each Employee’s yearly salary again.

Employee 1: Bob Jones; Yearly Salary: $34,500.00
Employee 2: Susan Baker; Yearly Salary: $37,809.00
 
Increasing employee salaries by 10%
 
Employee 1: Bob Jones; Yearly Salary: $37,950.00
Employee 2: Susan Baker; Yearly Salary: $41,589.90

Tips

  1. Class Employee should declare three instance variables.
  2. The constructor must declare three parameters, one for each instance variable. The value for the salary should be validated to ensure it is not negative.
  3. Declare a public set() and get() method for each instance variable. The set() methods should not return values and should each specify a parameter of a type that matches the corresponding instance variable: String for first name and last name, double for the salary. The get() methods should receive no parameters and should specify a return type that matches the corresponding instance variable.
  4. When you call the constructor from the test class EmployeeTest, you must pass it three arguments that match the parameters declared by the constructor.
  5. Giving each Employee a raise will require a call to the getSalary() method for the salary to obtain the current salary and a call to the setSalary() method for the salary to specify the new salary.
  6. A salary is a dollar amount, so you should output the salary using the "%.2f" specifier to provide two digits of precision. You should also include a thousand separator.
Solution
Employee.java
public class Employee {
  private String firstName;
  private String lastName;
  private double salary;
 
  public Employee(String firstName, String lastName, double salary) {
    this.firstName = firstName;
    this.lastName = lastName;
    this.salary = salary;
  }
 
  public String getFirstName() { return firstName; }
  public void setFirstName(String firstName) { this.firstName = firstName; }
 
  public String getLastName() { return lastName; }
  public void setLastName(String lastName) { this.lastName = lastName; }
 
  public double getSalary() { return salary; }
  public void setSalary(double salary) {
    if (salary > 0.0) {
      this.salary = salary;
    } else {
      this.salary = 0.0;
    }
  }
}
EmployeeTest.java
public class EmployeeTest {
  public static void main(String[] args) {
    Employee employee1 = new Employee("Dane", "Doe", 34500);
    Employee employee2 = new Employee("Zane", "Doe", 37809);
 
    System.out.printf("Employee 1: %s %s; Yearly Salary: $%,.2f%n",
                      employee1.getFirstName(), employee1.getLastName(),
                      employee1.getSalary());
    System.out.printf("Employee 2: %s %s; Yearly Salary: $%,.2f%n",
                      employee2.getFirstName(), employee2.getLastName(),
                      employee2.getSalary());
 
    System.out.println();
    System.out.println("Increasing employee salaries by 10%");
    System.out.println();
 
    employee1.setSalary(employee1.getSalary() * 1.1);
    employee2.setSalary(employee2.getSalary() * 1.1);
 
    System.out.printf("Employee 1: %s %s; Yearly Salary: $%,.2f%n",
                      employee1.getFirstName(), employee1.getLastName(),
                      employee1.getSalary());
    System.out.printf("Employee 2: %s %s; Yearly Salary: $%,.2f%n",
                      employee2.getFirstName(), employee2.getLastName(),
                      employee2.getSalary());
  }
}

Exercise 6+

Invoice Class

Create a class called Invoice that a hardware store might use to represent an invoice for an item sold at the store. An Invoice should include four pieces of information as instance variables:

  1. a part number: type String,
  2. a part description: type String,
  3. a quantity of the item being purchased: type int, and
  4. a price per item: type double.

Your class should have a constructor that initializes the four instance variables. Provide a set() and a get() method for each instance variable. In addition, provide a method named getInvoiceAmount() that calculates the invoice amount, that is, multiplies the quantity by the price per item then returns the amount as a double value. If the quantity is not positive, it should be set to 0. If the price per item is not positive, it should be set to 0.0.

Invoice-partNumber : String-description : String-quantity : int-pricePerItem : double+Invoice(String, String, int, double)+getPartNumber() : String+setPartNumber(String) : void+getDescription() : String+setDescription(String) : void+getQuantity() : int+setQuantity(int) : void+getPricePerItem() : double+setPricePerItem(double) : void+getInvoiceAmount() : double

Write a test application named InvoiceTest that demonstrates class Invoice’s capabilities.

Solution
Invoice.java
public class Invoice {
  private String partNumber;
  private String description;
  private int quantity;
  private double pricePerItem;
 
  public Invoice(String partNumber, String description, int quantity,
                 double pricePerItem) {
    this.partNumber = partNumber;
    this.description = description;
    this.quantity = quantity;
    this.pricePerItem = pricePerItem;
  }
 
  public String getPartNumber() { return partNumber; }
  public void setPartNumber(String partNumber) { this.partNumber = partNumber; }
 
  public String getDescription() { return description; }
  public void setDescription(String description) {
    this.description = description;
  }
 
  public int getQuantity() { return quantity; }
  public void setQuantity(int quantity) { this.quantity = quantity; }
 
  public double getPricePerItem() { return pricePerItem; }
  public void setPricePerItem(double pricePerItem) {
    this.pricePerItem = pricePerItem;
  }
 
  public double getInvoiceAmount() {
    if (quantity < 0) {
      quantity = 0;
    }
 
    if (pricePerItem < 0.0) {
      pricePerItem = 0.0;
    }
 
    return quantity * pricePerItem;
  }
}
InvoiceTest.java
public class InvoiceTest {
  public static void main(String[] args) {
    Invoice invoice =
        new Invoice("SQ74983948", "Graphics Processing Unit", 2, 2500);
    System.out.println("Invoice Amount: " + invoice.getInvoiceAmount());
  }
}