Polymorphism and instanceof - java

I have programed a Worker and MachineWorker class. It complies fine. but when i run it, after three consecutive statements the program stops. I cannot find the problem, and I dont know how and when to use 'instanceof'.
I am writing the question below and with all the classes...
Question:- (i)Declare an array that can store the references of up to 5 Worker or MachineWorker objects.
a)Allow user to enter the type of object and the data for that type of object(3 values for Worker and 4 values for MachineWorker).
b)Construct the appropriate object storing the reference in the common array.
ii)Now allow the users to enter the weekly data repeatedly. If it is Worker object user must enter ID and hours-worked. If it is a MachineWorker object user must enter ID,hoursWorked and pieces. Once these values read search through the array to locate the object with the given ID before calling the addWeekly().The number of arguments either(1 or 2) to be passed to addWeekly depends on the type of objects being referred. To determine the type of object being referred(Worker or MachineWorker)you may use the instanceof operator.
Please see my codes below:-
//Worker.java
public class Worker {
public final double bonus=100;
protected String name, workerID;
protected double hourlyRate, totalHoursWorked,tax,grossSalary,netSalary;
public Worker(){
}
public Worker(String name, String workerID, double hourlyRate){
this.name = name;
this.workerID = workerID;
this.hourlyRate = hourlyRate;
}
public void addWeekly(double hoursWorked){
this.totalHoursWorked = this.totalHoursWorked + hoursWorked;
}
public double gross(){
grossSalary = (totalHoursWorked*hourlyRate);
if(totalHoursWorked>=150){
grossSalary = grossSalary +100;
}
return grossSalary;
}
public double netAndTax(){
netSalary = grossSalary;
if(grossSalary>500){
tax = (grossSalary - 500) *0.3;
netSalary = (grossSalary - tax);
}
return netSalary;
}
public String getName(){
return this.name;
}
public String getWorkerID(){
return this.workerID;
}
public double getHourlyRate(){
return this.hourlyRate;
}
public double getTotalHours(){
return totalHoursWorked;
}
public double getGrossSalary(){
return grossSalary;
}
public void addToGross(double amt){
grossSalary = grossSalary + amt;
}
public void displaySalary(){
System.out.print("Name: " +getName() + "\nID :" + getWorkerID()
+ "\nHourly Rate: " + getHourlyRate()+ "\nTotalHours Worked" + getTotalHours() +
"\nGross pay" + getGrossSalary() + "\nTax: " + netAndTax() +
"\nNet Pay: " + netAndTax());
}
}
//MachineWorker.java
public class MachineWorker extends Worker{
private double targetAmount;
private double totalPieces, productivityBonus;
public MachineWorker(String workerName, String workerID, double hourlyRate, double targetAmount)
{
super(workerName, workerID, hourlyRate);
//this.productivityBonus = productivityBonus;
this.targetAmount = targetAmount;
}
public void addWeekly(double hoursWorked, double weeklyAmount)
{
totalHoursWorked = hoursWorked + totalHoursWorked;
totalPieces = weeklyAmount + totalPieces;
}
public double productivityBonus()
{
productivityBonus = 100 + (totalPieces - targetAmount);
return productivityBonus;
}
public double gross()
{
grossSalary = (totalHoursWorked * hourlyRate) + productivityBonus;
if(totalHoursWorked >= 150)
{
grossSalary = grossSalary + bonus;
}
return grossSalary;
}
public void addToGross(double amt)
{
amt = productivityBonus;
grossSalary = grossSalary + amt;
}
public void displaySalary()
{
System.out.println("Name " + super.name + "\nID " +
super.workerID + "\nHourly rate " + super.hourlyRate + "\nTotal Hours Worked " +
super.totalHoursWorked + "\nGross Pay $" + super.grossSalary + "\nTax $" + super.tax + "\nNetpay $" + super.netSalary);
System.out.println("Productivity Bonus " + productivityBonus);
}
}
//Polymorphism PolyWorker.java
import java.util.*;
public class PolyWorkers
{
public static void main(String args[])
{
Scanner input = new Scanner(System.in);
Worker[] a = new Worker[5];
MachineWorker[] b = new MachineWorker[5];
char option = '0';
String choice;
boolean nChar = false;
for (int i = 0; i < 5; i++){
System.out.print("\tType of object " + (i+1) + " [W/M]: ");
choice = input.nextLine();
if (choice.length() == 1)
{
option = choice.charAt(0); //pick the first character
if (option == 'w' || option == 'W')
{
System.out.println("\n\tEnter name, ID and hours: ");
String name = input.nextLine();
System.out.print(" ");
String id = input.nextLine();
System.out.print(" ");
double hours = input.nextDouble();
a[i] = new Worker(name, id, hours);
System.out.println();
}
if (option == 'm' || option == 'M')
{
System.out.print("\n\tEnter name, ID, hours and pieces: ");
String name = input.nextLine();
System.out.print(" ");
String id = input.nextLine();
System.out.print(" ");
double hours = input.nextDouble();
System.out.print(" ");
double pieces = input.nextDouble();
b[i] = new MachineWorker(name, id, hours, pieces);
System.out.println();
}
System.out.print("\tType of object " + (i+1) + " [W/M]: ");
choice = input.nextLine();
}
a[i].displaySalary();
b[i].displaySalary();
b[i].productivityBonus();
}
}
}

You might want to use overriden methods readfromInput and displaySalary to distinguish between what Worker and Machinworker does.
The different behaviour should be implemented within the classes and not in the calling Polyworker class.
If Machineworker displaySalary shows the bonus this should be called in displaySalary of MachineWorker
see modified code below
//Worker.java
import java.util.Scanner;
/**
* a generic worker
*/
public class Worker {
public final double bonus = 100;
protected String name, workerID;
protected double hourlyRate, totalHoursWorked, tax, grossSalary, netSalary;
public void addWeekly(double hoursWorked) {
this.totalHoursWorked = this.totalHoursWorked + hoursWorked;
}
public double gross() {
grossSalary = (totalHoursWorked * hourlyRate);
if (totalHoursWorked >= 150) {
grossSalary = grossSalary + 100;
}
return grossSalary;
}
public double netAndTax() {
netSalary = grossSalary;
if (grossSalary > 500) {
tax = (grossSalary - 500) * 0.3;
netSalary = (grossSalary - tax);
}
return netSalary;
}
public String getName() {
return this.name;
}
public String getWorkerID() {
return this.workerID;
}
public double getHourlyRate() {
return this.hourlyRate;
}
public double getTotalHours() {
return totalHoursWorked;
}
public double getGrossSalary() {
return grossSalary;
}
public void addToGross(double amt) {
grossSalary = grossSalary + amt;
}
public void displaySalary() {
System.out.print("Name: " + getName() + "\nID :" + getWorkerID()
+ "\nHourly Rate: " + getHourlyRate() + "\nTotalHours Worked"
+ getTotalHours() + "\nGross pay" + getGrossSalary() + "\nTax: "
+ netAndTax() + "\nNet Pay: " + netAndTax());
}
public void readFromInput(Scanner input) {
name = input.nextLine();
System.out.print(" ");
this.workerID= input.nextLine();
System.out.print(" ");
this.totalHoursWorked = input.nextDouble();
System.out.println();
}
} // Worker
//MachineWorker.java
import java.util.Scanner;
public class MachineWorker extends Worker {
private double targetAmount;
private double totalPieces, productivityBonus;
public void addWeekly(double hoursWorked, double weeklyAmount) {
totalHoursWorked = hoursWorked + totalHoursWorked;
totalPieces = weeklyAmount + totalPieces;
}
public double productivityBonus() {
productivityBonus = 100 + (totalPieces - targetAmount);
return productivityBonus;
}
public double gross() {
grossSalary = (totalHoursWorked * hourlyRate) + productivityBonus;
if (totalHoursWorked >= 150) {
grossSalary = grossSalary + bonus;
}
return grossSalary;
}
public void addToGross(double amt) {
amt = productivityBonus;
grossSalary = grossSalary + amt;
}
#Override
public void displaySalary() {
super.displaySalary();
System.out.println("Productivity Bonus " + productivityBonus);
}
#Override
public void readFromInput(Scanner input) {
super.readFromInput(input);
this.totalPieces = input.nextDouble();
}
}
//Polymorphism PolyWorker.java
import java.util.*;
public class PolyWorkers {
public static void main(String args[]) {
Scanner input = new Scanner(System.in);
Worker[] workers = new Worker[5];
char option = '0';
String choice;
for (int i = 0; i < 5; i++) {
System.out.print("\tType of object " + (i + 1) + " [W/M]: ");
choice = input.nextLine();
if (choice.length() == 1) {
option = choice.toLowerCase().charAt(0); // pick the first character
switch (option) {
case 'w': {
workers[i] = new Worker();
System.out.println("\n\tEnter name, ID and hours: ");
}
break;
case 'm': {
System.out.print("\n\tEnter name, ID, hours and pieces: ");
}
break;
} // switch
workers[i].readFromInput(input);
}
workers[i].displaySalary();
}
}
}

Your question states that you have to store the references in a common array, where as you are storing them in 2 different arrays a and b. As you have different arrays for different type of objects, you don't have the need to use instanceOf operator. More about instanceOf is here.
Also, you do not check for null while printing salary or bonus. As at any point of the loop, only one type of object will be created, one of a[i] or b[i] will be definitely null, causing a NullPointerException.

You need another loop after the one you have already written that will allow the user to input the worker's hours. This will presumably be a while loop that will continually ask for input. You would then choose some sort of input that would quit the loop. Inside the loop you ask for hours and take either 2 or 3 arguments.
At the moment you are not storing your Workers/MachineWorkers. You need to create an array to store them in. You also need to create either a base class or an interface that they will both extend/implement. This will allow you to create a single array to store them all.
You then loop through your array of Workers/MachineWorkers and when you find a matching id you use your instanceof to work out whether you need to pass 1 or 2 arguments. If it is a MachineWorker you should cast it as such and then call the appropriate method with 2 arguments.

Related

Finding the highest and the lowest value

I have this assignment I gotta do. It looks good, except for the getHighest output and the getLowest result. Here's my code:
KNW_CourseGradesV2 Class:
public class KNW_CourseGradesV2 implements KNW_Analyzable
{
//Declare array variable
private KNW_GradedActivity[] grades = new KNW_GradedActivity[4];
String results;
/**
* Constructor
* */
public KNW_CourseGradesV2()
{
}
public void setLab(KNW_GradedActivity lab)
{
grades[0] = lab;
}
public void setPassFailExam(KNW_GradedActivity pfe)
{
grades[1] = pfe;
}
public void setEssay(KNW_GradedActivity essay)
{
grades[2] = essay;
}
public void setFinalExam(KNW_FinalExam fe)
{
grades[3] = fe;
}
public void setTotalGrade(KNW_GradedActivity tg)
{
grades[4] = tg;
}
public String toString()
{
//Lay out all of the scores
return "Lab Score: " + grades[0].getScore() +
"\tGrade: " + grades[0].getGrade() +
"\nPass/Fail Exam: " + grades[1].getScore() +
"\tGrade: " + grades[1].getGrade() +
"\nEssay Score: " + grades[2].getScore() +
"\tGrade: " + grades[2].getGrade() +
"\nFinal Exam Score: " + grades[3].getScore() +
"\tGrade: " + grades[3].getGrade();
}
//Find the average of the grades
public double getAverage()
{
double sum = 0.0;
double average = 0.0;
double total = 0.0;
//For loop to calc. the average
for(int i =0; i<grades.length; i++)
{
total =+ grades[i].getScore();
average = sum/grades.length;
}
return average;
}
public KNW_GradedActivity getHighest()
{
double highest = grades[0].getScore();
for(int i = 0; i < grades.length; i++)
{
if(grades[i].getScore() > highest)
{
highest = grades[i].getScore();
}
}
//Created KNW_GradedActivity object to bring the highest number
//into the setScore method so it can be a double
KNW_GradedActivity gaH = new KNW_GradedActivity();
gaH.setScore(highest);
return gaH;
}
public KNW_GradedActivity getLowest()
{
double lowest = grades[0].getScore();
for(int i = 0; i < grades.length; i++)
{
if(grades[i].getScore() > lowest)
{
lowest = grades[i].getScore();
}
}
//Samething here, just doing it for the lowest number
KNW_GradedActivity gaL = new KNW_GradedActivity();
gaL.setScore(lowest);
return gaL;
}
}
KNW_Analyzable Class:
public interface KNW_Analyzable
{
double getAverage();
KNW_GradedActivity getHighest();
KNW_GradedActivity getLowest();
}
KNW_GradedActivity Class:
public class KNW_GradedActivity
{
private double score; // Numeric score
/**
The setScore method sets the score field.
#param s The value to store in score.
*/
public void setScore(double s)
{
score = s;
}
/**
The getScore method returns the score.
#return The value stored in the score field.
*/
public double getScore()
{
return score;
}
/**
The getGrade method returns a letter grade
determined from the score field.
#return The letter grade.
*/
public char getGrade()
{
char letterGrade;
if (score >= 90)
letterGrade = 'A';
else if (score >= 80)
letterGrade = 'B';
else if (score >= 70)
letterGrade = 'C';
else if (score >= 60)
letterGrade = 'D';
else
letterGrade = 'F';
return letterGrade;
}
}
And here is the output I get. I will just show the problem I am facing, won't show all of the output.
Output:
Average: 0.0
Highest: KNW_GradedActivity#565d3fa7
Lowest: KNW_GradedActivity#655c4395>
I have been trying for about a week to figure this out and find what is happening, and I can't seem to find it.
Notice that in the return of your methods, you are actually returning gaH and gaL, both of which are KNW_GradedActivity Objects. If you want to see the score, you should probably return gaH.getScore() and gaL.getScore().
Why not to use Stream and DoubleSummaryStatistics to get the stats? Let the api do all the calculations:
List<KNW_GradedActivity> grades = Arrays.asList(new KNW_GradedActivity(), new KNW_GradedActivity(), new KNW_GradedActivity());
grades.get(0).setScore(91);
grades.get(1).setScore(81);
grades.get(2).setScore(71);
DoubleSummaryStatistics statistics = grades.stream().
collect(Collectors.summarizingDouble(KNW_GradedActivity::getScore));
System.out.println(statistics);
// DoubleSummaryStatistics{count=3, sum=243.000000, min=71.000000, average=81.000000, max=91.000000}
Another alternative is to override toString method in your KNW_GradedActivity class:
#Override
public String toString() {
return "{" +
"score=" + score +
", grade='" + getGrade() + '\'' +
'}';
}
This way you dont have to change your actual print statement and will have a nice output combining your score and grade. It will look like:
{score=90.0, grade='A'}

Array List Average

I'm trying to figure out how to get the Max & Min accounts to also print prints its account number, balance and average transaction amount.
I've tried all sorts of garb and have gotten nowhere.
import java.util.ArrayList;
import java.util.Scanner;
public class BankAccount {
private int AccountNumber;
public int getAccountNumber()
{
return AccountNumber;
}
private double Balance;
public double getBalance()
{
return Balance;
}
private ArrayList<Double> transactions = new ArrayList<Double>();
public void Deposit(double Balance)
{
transactions.add(Balance);
this.Balance = this.Balance + Balance;
}
public void Withdraw(double Balance)
{
transactions.add(-Balance);
this.Balance = this.Balance - Balance;
}
public BankAccount(int initialAccountNumber, double initialBalance)
{
this.Balance = initialBalance;
this.AccountNumber = initialAccountNumber;
transactions.add(initialBalance);
}
public double getAverage()
{
double sum = 0;
for (double element : transactions)
{
sum = sum + Math.abs(element);
}
double Average = sum / transactions.size();
return Average;
}
}
---
import java.util.ArrayList;
public class Bank {
private ArrayList<BankAccount> accounts = new ArrayList<BankAccount>();
public void MakeAccount(int initialAccountNumber, double initialBalance)
{
BankAccount NewAcc = new BankAccount(initialAccountNumber, initialBalance);
accounts.add(NewAcc);
}
public BankAccount FindLarAcc(int initialAccountNumber, double initialBalance)
{
BankAccount largest = accounts.get(0);
for (int i = 1; i < accounts.size(); i++)
{
BankAccount a = accounts.get(i);
if (a.getBalance() > largest.getBalance())
largest = a;
}
return largest;
}
public BankAccount FindLowAcc(int initialAccountNumber, double initialBalance)
{
BankAccount smallest = accounts.get(0);
for (int i = 1; i < accounts.size(); i++)
{
BankAccount a = accounts.get(i);
if (a.getBalance() < smallest.getBalance())
smallest = a;
}
return smallest;
}
public BankAccount FindAcc(int initialAccountNumber)
{
for (BankAccount a: accounts)
{
if (a.getAccountNumber() == initialAccountNumber)
return a;
}
return null;
}
}
---
import java.util.Scanner;
public class BankTester {
public static void main(String[] args){
Scanner in = new Scanner (System.in);
/**int AccountNumber = 0;*/
double Balance = 0;
double Amount = 0;
Bank Bank1 = new Bank();
boolean done = false;
while (!done)
{
System.out.println("Enter an Account Number to begin, enter -1 to quit: ");
int AccountNumber = in.nextInt();
if (AccountNumber == -1)
{
done = true;
} else {
System.out.println("Now enter a Balance: ");
Balance = in.nextDouble();
Bank1.MakeAccount(AccountNumber, Balance);
BankAccount B = Bank1.FindAcc(AccountNumber);
System.out.println("How much would you like to deposit? ");
Amount = in.nextDouble();
B.Deposit(Amount);
System.out.println("How much would you like to withdrawl? ");
Amount = in.nextDouble();
B.Withdraw(Amount);
}
BankAccount Max = Bank1.FindLarAcc(AccountNumber, Balance);
BankAccount Min = Bank1.FindLowAcc(AccountNumber, Balance);
/**
* Print & Compute Average
*/
System.out.println("Account " + Min.getAccountNumber() +
" has the smallest balance. ");
System.out.println("Account " + Max.getAccountNumber() +
" has the largest balance. ");
}
}
}
For those who might have had the same problem...I figured it out!
This belongs on the BankTester class, btw
System.out.println("Account " + Min.getAccountNumber() +
" has the smallest balance of, " + Min.getBalance() +
" and a average transaction of, " + Min.getAverage());
System.out.println("Account " + Max.getAccountNumber() +
" has the largest balance of, " + Max.getBalance() +
" and a average transaction of, " + Max.getAverage());

How to get the total of each column

Its been a ridiculous task especially to build the total of each vertical column & to show it on screen. Though, calculating the total of horizontal row never seemed to be a challenge.
The problem I'm having is three-fold.
How do I calculate the total of each vertical column ?
The index (id) is getting printed in descending order. How do I make it print in ascending order ?
Further, in the percentage column the value after the decimal point is being discarded. How do I get that displayed? For eg.. if
answer is supposed to be 78.25% it exhibits as 78.0%
P.S : (2 places after the decimal point is what I'm aiming at.)
POJO class -- StudentsProg.java
package com.students.marks;
import java.util.Arrays;
public class StudentsProg {
private int id = 0;
private String name;
private int english;
private int german;
private int french;
private int arabic;
private double percentage;
private int total_marks;
private int rowHighest;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getEnglish() {
return english;
}
public void setEnglish(int english) {
this.english = english;
}
public int getGerman() {
return german;
}
public void setGerman(int german) {
this.german = german;
}
public int getFrench() {
return french;
}
public void setFrench(int french) {
this.french = french;
}
public int getArabic() {
return arabic;
}
public void setArabic(int arabic) {
this.arabic = arabic;
}
public double getPercentage() {
return percentage;
}
public void setPercentage(double percentage) {
this.percentage = percentage;
}
public int getTotal_marks() {
return total_marks;
}
public void setTotal_marks(int total_marks) {
this.total_marks = total_marks;
}
public int getRowHighest() {
return rowHighest;
}
public void setRowHighest(int rowHighest) {
this.rowHighest = rowHighest;
}
public String toString() {
id = id+1;
return (id + "\t" +name+ "\t\t" +english+ "\t" + " " +german+ "\t" + " "+ french+ "\t" + " " +arabic+ "\t" +" " +total_marks+ "\t\t" + " " +percentage+ "\t\t" +rowHighest);
}
}
StudentsProgMain.java
import java.util.Scanner;
public class StudentsProgMain {
#SuppressWarnings("resource")
public static void main(String[] args) {
int count = 0;
StudentsProg[] stud = new StudentsProg[15];
int choice=0;
int max = 0;
Scanner scanner = new Scanner(System.in);
do{
System.out.println("1: Add new Student");
System.out.println("2: List Student");
System.out.println("3: List Student By Name.");
System.out.println("4: Delete Student");
System.out.println("5: Exit");
System.out.println("Please enter your choice \n\n");
choice=scanner.nextInt();
switch(choice){
case 1:
stud[count] = new StudentsProg();
System.out.println("Enter student name");
stud[count].setName(scanner.next());
System.out.println("Enter marks in English");
stud[count].setEnglish(scanner.nextInt());
System.out.println("Enter marks in German");
stud[count].setGerman(scanner.nextInt());
System.out.println("Enter marks in French");
stud[count].setFrench(scanner.nextInt());
System.out.println("Enter marks in Arabic");
stud[count].setArabic(scanner.nextInt());
count++;
break;
case 2:
System.out.println("ID\t" + "Name \t\t\t" + "English\t" + " " + "German\t"+ " " + "French\t" + " " + "Arabic\t"
+" "+ "Total Marks\t" + " " + "Percentage\t" + "Highest Marks(Row)\n" +
"------------------------------------------------------------------------"
+ "------------------------------------------- \n ");
for(int i=0; i<count; i++){
if(stud[i]!=null){
int total_marks = stud[i].getEnglish()+stud[i].getGerman()+ stud[i].getFrench()+stud[i].getArabic();
stud[i].setTotal_marks(total_marks);
double calc_per = ((total_marks*100)/400);
stud[i].setPercentage(calc_per);
int arrayListMarks [] = {stud[i].getEnglish(), stud[i].getFrench(), stud[i].getGerman(), stud[i].getArabic()};
max = arrayListMarks[0];
for (int j = 1; j < arrayListMarks.length; j++) {
if(arrayListMarks[j] > max)
max = arrayListMarks[j]; }
stud[i].setRowHighest(max);
System.out.println(stud[i].toString());
System.out.println("\n");}
}
System.out.println("--------------------------------------------------------------"
+ "----------------------------------------------------- \n");
System.out.println("\tTotal :" +"\n");
break;
case 3 :
System.out.println("Please enter your name");
String name = scanner.next();
System.out.println("\n" + "ID\t" + "Name \t\t\t" + "English\t" + " " + "German\t"+ " " + "French\t" + " " + "Arabic\t"
+" "+ "Total Marks\t" + " " + "Percentage\t" + "Highest Marks(Row)\n" +
"------------------------------------------------------------------------"
+ "------------------------------------------- \n ");
for(int i =0 ; i<count; i++){
if(stud[i]!=null && stud[i].getName().equals(name))
System.out.println(stud[i].toString()); }
System.out.println("--------------------------------------------------------------"
+ "----------------------------------------------------- \n");
break;
case 4 :
System.out.println("Please enter your name");
String naam = scanner.next();
for (int i = 0; i<count; i++) {
if(stud[i]!=null && stud[i].getName()==naam)
stud[i]=null;
}
break;
case 5:
System.exit(0);
System.out.println("You have exited successfully");
default :
System.out.println("Invalid choice");
}
}while(true);
}
}
The problem with the percentage calculation is that the line of code double calc_per = ((total_marks*100)/400); will do integer arithmetic and truncate each intermediate result as an integer. To fix this you need to include a floating point number somewhere in the calculation either by converting total_marks to double like so:
double calc_per = ((Integer.valueOf(total_marks).doubleValue()*100)/400);
Or using a float constant like so:
double calc_per = ((total_marks*100.0)/400);
Vertical totals should just be a matter of adding the row value to a variable inside your print loop.
I'm not really sure about your index order problem but the code in toString() that reads id = id+1; looks wrong. This will increment the Id each time you call toString(). Instead of that, your creation code should set the value of id just after creating the object, something like:
stud[count] = new StudentsProg();
// add the following line of code.
stud[count].setId(count);
System.out.println("Enter student name");
stud[count].setName(scanner.next());

Why am I getting the error "the Method Is Undefined for the type"?

I am learning the basics at University and would like some help with the following error from Eclipse : "The method getCost() is undefined for the type ShopCLI" &
"Exception in thread "main" java.lang.Error: Unresolved compilation problem:
The method getCost() is undefined for the type ShopCLI
at components.ShopCLI.main(ShopCLI.java:39)
Here is my code
public class ShopCLI {
public static void main(String[] args) {
ArrayList<Order> ord = new ArrayList<>();
System.out.println("Welcome to Sandwich Shop CLI V1!");
System.out.println("Please Choose and Option by Typing the Appropriate Number from the List");
System.out.println("1.New Order");
Scanner sc = new Scanner(System.in);
int choice = sc.nextInt();
System.out.println("Please Choose an Outer From the List: ");
System.out.println("Press 1 to Continue or 2 to Exit");
int Sandwich = sc.nextInt();
System.out.println("Outer Options are Bun, Bread or Brioche");
String inputOuter = sc.next();
System.out.println("Inner Options are Ham, Cheese or Cucumber");
String inputInner = sc.next();
System.out.println("Sauce Options are Mayo, Butter or Marmite");
String inputSauce = sc.next();
if (Sandwich == 1){
ord.add(new Order(1, inputOuter, inputInner, inputSauce, 0));
System.out.println("You Made a " + inputInner + " with " + inputSauce + " Sandwich on " + inputOuter);
System.out.println("This Will Cost " + getCost());
}
else if (Sandwich == 2){
System.out.println("Exited.");
}
}
}
public class Sandwich {
//Fields
ArrayList<Sandwich> sandwich = new ArrayList<>();
String outer;
String inner;
String sauce;
//Constructor
public Sandwich(String outer, String inner, String sauce){
this.outer = outer;
this.inner = inner;
this.sauce = sauce;
}
//Methods
public String getOuter(){
return outer;
}
public String getInner(){
return inner;
}
public String getSauce(){
return sauce;
}
public void setOuter(String repOuter){
outer = repOuter;
}
public void setInner(String repInner){
inner = repInner;
}
public void setSauce(String repSauce){
sauce = repSauce;
}
public void createSandwich(String outer, String inner, String sauce){
sandwich.add(new Sandwich(outer, inner, sauce));
}
public void setSandwich(String repOuter, String repInner, String repSauce){
outer = repOuter;
inner = repInner;
sauce = repSauce;
}
public void resetOrder(){
sandwich.removeAll(sandwich);
}
}
public class Order extends Sandwich {
//Fields
int OrderId;
double Cost;
//Constructor
public Order(int OrderId, String outer, String inner, String sauce, int Cost) {
super(outer, inner, sauce);
this.OrderId = OrderId;
this.Cost = Cost;
}
//Methods
public int getOrderId(){
return this.OrderId;
}
public double getCost(){
return this.Cost;
}
public void setOrderId(int repOrderID){
this.OrderId = repOrderID;
}
public void overrideCost(int Cost){
this.Cost = Cost;
}
public void setOrder(int repOrderId, String repOuter, String repInner, String repSauce){
this.OrderId = repOrderId;
this.outer = repOuter;
this.inner = repInner;
this.sauce = repSauce;
double calcCost;
double outerCost = 0;
double innerCost = 0;
double sauceCost = 0;
//Outer Cost
if(repOuter == "Bun")
{
outerCost = 0.5;
}
else if(repOuter == "Bread")
{
outerCost = 0.25;
}
else if(repOuter == "Brioche")
{
outerCost = 0.75;
}
else
{
System.out.println("Invalid Bread Type");
}
//Inner cost
if(repInner == "Ham")
{
innerCost = 0.5;
}
else if(repInner == "Cheese")
{
innerCost = 0.25;
}
else if(repInner == "Cucumber")
{
innerCost = 0.75;
}
else
{
System.out.println("Invalid Filling Type");
}
//Sauce Cost
if(repSauce == "Mayo")
{
sauceCost = 0.5;
}
else if(repSauce == "Butter")
{
sauceCost = 0.25;
}
else if(repSauce == "Marmite")
{
sauceCost = 0.75;
}
else
{
System.out.println("Invalid Sauce Type");
}
calcCost = outerCost + innerCost + sauceCost;
this.Cost = calcCost;
}
}
getCost method is defined in order class and not in ShopCLI class. So your code:
ord.add(new Order(1, inputOuter, inputInner, inputSauce, 0));
System.out.println("You Made a " + inputInner + " with " + inputSauce + " Sandwich on " + inputOuter);
System.out.println("This Will Cost " + getCost());
Should be changed to
Order order = new Order(1, inputOuter, inputInner, inputSauce, 0);
ord.add(order);
System.out.println("You Made a " + inputInner + " with " + inputSauce + " Sandwich on " + inputOuter);
System.out.println("This Will Cost " + order.getCost());
^^^^^
you must get the object from the arraylist, then do acces the method:
//get obj,then void
System.out.println("This Will Cost " + ord.get(choise).getCost());
this will return 0, since you set the cost 0 in the constructor:
ord.add(new Order(1, inputOuter, inputInner, inputSauce, 0));
also, name your integer "Sandwich" to "sandwich" without the capital letter. otherwise, it looks like you mean the class "Sandwich"
In this line:
System.out.println("This Will Cost " + getCost());
...you don't specify what you want to call getCost() on, so it calls it on ShopCLI because that's where the call is happening. But ShopCLI doesn't have a getCost() method. You need to call it on your order:
System.out.println("This Will Cost " + ord.get(0).getCost());
This works, but when you create your Order object by calling the constructor, you're not calculating the cost, but rather setting whatever is passed in. Update your constructor to this:
//Constructor
public Order(int OrderId, String outer, String inner, String sauce) {
super(outer, inner, sauce);
this.OrderId = OrderId;
double calcCost;
double outerCost = 0;
double innerCost = 0;
double sauceCost = 0;
//Outer Cost
if(outer == "Bun")
{
outerCost = 0.5;
}
else if(outer == "Bread")
{
outerCost = 0.25;
}
else if(outer == "Brioche")
{
outerCost = 0.75;
}
else
{
System.out.println("Invalid Bread Type");
}
//Inner cost
if(inner == "Ham")
{
innerCost = 0.5;
}
else if(inner == "Cheese")
{
innerCost = 0.25;
}
else if(inner == "Cucumber")
{
innerCost = 0.75;
}
else
{
System.out.println("Invalid Filling Type");
}
//Sauce Cost
if(sauce == "Mayo")
{
sauceCost = 0.5;
}
else if(sauce == "Butter")
{
sauceCost = 0.25;
}
else if(sauce == "Marmite")
{
sauceCost = 0.75;
}
else
{
System.out.println("Invalid Sauce Type");
}
calcCost = outerCost + innerCost + sauceCost;
this.Cost = calcCost;
}
Now your constructor works, but you will have to remove an argument where you're calling it, so change your ord.add line to this:
ord.add(new Order(1, inputOuter, inputInner, inputSauce));
That should, if I'm not mistaken work. However, you might want to consider making a private helper method called calculateCost, so that you're not duplicating code between your constructor and your setOrder methods.
Create an Order
Order order = new Order(1, inputOuter, inputInner, inputSauce, 0);
ord.add(order) // Add the order to your list.
The cost for an order is set by the method setOrder(int repOrderId, String repOuter, String repInner, String repSauce)
change this method to the following.
public void setOrder() {
double calcCost;
double outerCost = 0;
double innerCost = 0;
double sauceCost = 0;
// Outer Cost
if (outer.equalsIgnoreCase("Bun")) {
outerCost = 0.5;
} else if (outer.equalsIgnoreCase("Bread")) {
outerCost = 0.25;
} else if (outer.equalsIgnoreCase("Brioche")) {
outerCost = 0.75;
} else {
System.out.println("Invalid Bread Type");
}
// Inner cost
if (inner.equalsIgnoreCase("Ham")) {
innerCost = 0.5;
} else if (inner.equalsIgnoreCase("Cheese")) {
innerCost = 0.25;
} else if (inner.equalsIgnoreCase("Cucumber")) {
innerCost = 0.75;
} else {
System.out.println("Invalid Filling Type");
}
// Sauce Cost
if (sauce.equalsIgnoreCase("Mayo")) {
sauceCost = 0.5;
} else if (sauce.equalsIgnoreCase("Butter")) {
sauceCost = 0.25;
} else if (sauce.equalsIgnoreCase("Marmite")) {
sauceCost = 0.75;
} else {
System.out.println("Invalid Sauce Type");
}
calcCost = outerCost + innerCost + sauceCost;
this.Cost = calcCost;
}
Now you can get the cost by calling the getCost() on the order as follows.
To calculate the order cost, call
order.setOrder();
To get the order cost, call
order.getCost();
NOTE: Don't use == to compare string. Always use equals() or equalsIgnoreCase().
i have modified your code for class ShopCLI
package tester;
import java.util.ArrayList;
import java.util.Scanner;
public class ShopCLI {
public static void main(String[] args) {
ArrayList<Order> ord = new ArrayList<>();
int orderNumber =1;
System.out.println("Welcome to Sandwich Shop CLI V1!");
System.out.println("start order");
Scanner sc = new Scanner(System.in);
while(true){
System.out.println("Press 1 for new order or 2 to Exit");
int choice = sc.nextInt();
if (choice == 1){
System.out.println("Enter outer Options:Outer Options are Bun, Bread or Brioche");
String inputOuter = sc.next();
System.out.println("Enter inner Options:Inner Options are Ham, Cheese or Cucumber");
String inputInner = sc.next();
System.out.println("Enter sauce Options:Sauce Options are Mayo, Butter or Marmite");
String inputSauce = sc.next();
Order order1 = new Order(orderNumber, inputOuter, inputInner, inputSauce, 0);
order1.setOrder(inputOuter, inputInner, inputSauce);
System.out.println("You Made a " + inputInner + " with " + inputSauce + " Sandwich on " + inputOuter);
System.out.println("This Will Cost " + order1.getCost());
ord.add(order1);
}
else if (choice == 2){
System.out.println("Exited.");
System.exit(1);
}
}
}
}
and format of setOrder method is modified too
public void setOrder(String repOuter, String repInner, String repSauce)

Abstract Class error: Exception in thread "main" java.lang.NullPointerException

Heres the full error
Exception in thread "main" java.lang.NullPointerException
at EmployeeManager.addEmployee(EmployeeManager.java:38)
at EmployeeDriver.main(EmployeeDriver.java:231)
here is where the errors are coming from
public class EmployeeManager
{
private Employee[] employees;
private final int employeeMax = 100;
private int currentEmployees;
public EmployeeManager()
{
Employee[] employees = new Employee[employeeMax];
currentEmployees = 0;
}
public void addEmployee(int eType, String fn, String ln, char m, char g, int empNum, boolean ft, double a)
{
double sales = 0.0, hoursWorked = 0.0;
switch (eType)
{
/*error*/ case 1: employees[currentEmployees] = new HourlyEmployee(fn, ln, m, g, empNum, ft, a, hoursWorked);
currentEmployees++;
break;
case 2: employees[currentEmployees] = new SalaryEmployee(fn, ln, m, g, empNum, ft, a);
currentEmployees++;
break;
case 3: employees[currentEmployees] = new CommissionEmployee(fn, ln, m, g, empNum, ft, a, sales);
currentEmployees++;
break;
}
}
///////////////////////////////////////////////////////////////////////////////////////////
//Add Employee
case 2:
String fn, ln;
char mi, g, f;
boolean ft = true;
do
{
System.out.println("\n1. Hourly");
System.out.println("2. Salary");
System.out.println("3. Commission");
System.out.print("Enter Choice: ");
subInput1 = in.nextInt();
if(subInput1 < 1 || subInput1 > 3)
{
System.out.println("Invalid Choice! Choose again.");
}
}while(subInput1 < 1 || subInput1 > 3);
System.out.print("Enter Last Name: ");
ln = in.next();
System.out.print("Enter First Name: ");
fn = in.next();
System.out.print("Enter Middle Initial: ");
mi = in.next().charAt(0);
System.out.print("Enter Gender: ");
g = in.next().charAt(0);
System.out.print("Enter Employee Number: ");
en = in.nextInt();
System.out.print("Full Time? (y/n): ");
f = in.next().charAt(0);
if(f == 'n' || f == 'N')
{
ft = false;
}
if(subInput1 == 1)
{
System.out.print("Enter wage: ");
}
else if(subInput1 == 2)
{
System.out.print("Enter salary: ");
}
else
{
System.out.print("Enter rate: ");
}
amount = in.nextDouble();
/*error*/ em.addEmployee(subInput1, fn, ln , mi, g, en, ft, amount);
em.removeRedundancies();
break;
Now as far as i am concerned i am making a new instantiation of HourlyEmployee which holds all of these values in the employees array. HourlyEmployee is a subclass of superclass Employee. Here's my code for those two.
public class HourlyEmployee extends Employee
{
private double wage;
private double hoursWorked;
public HourlyEmployee(String fn, String ln, char m, char g, int empNum, boolean ft, double w, double h)
{
super (fn, ln, m, g, empNum, ft);
wage = w;
hoursWorked = h;
hoursWorked = 0.0;
}
#Override
public String toString()
{
return this.getEmployeeNumber() + "\n" + lastName + ", " + firstName + middleInitial + "\n" + "Gender: "
+ this.getGender() + "\n" + "Status: " + fulltime + "\n" + "Wage: " + wage + "\n" + "Hours Worked: " + hoursWorked + "\n";
}
#Override
public double calculateWeeklyPay()
{
if (hoursWorked > 40)
{
wage = wage * 2;
}
return wage * hoursWorked;
}
#Override
public void annualRaise()
{
wage = (wage * .05) + wage;
}
#Override
public double holidayBonus()
{
return wage * 40;
}
#Override
public void resetWeek()
{
hoursWorked = 0.0;
}
public double plusHoursWorked(double amount, double h)
{
while (amount <= 0)
{
System.out.println("Invalid value entered, please try again");
}
return amount + h;
}
}
///////////////////////////////////////////////////////////////////////////////////////////
public abstract class Employee
{
protected String firstName;
protected String lastName;
protected char middleInitial;
protected boolean fulltime;
private char gender;
private int employeeNum;
public Employee (String fn, String ln, char m, char g, int empNum, boolean ft)
{
firstName = fn;
lastName = ln;
middleInitial = m;
gender = g;
employeeNum = empNum;
fulltime = ft;
}
public int getEmployeeNumber()
{
return employeeNum;
}
public void setEmployeeNumber(int empNum)
{
while (empNum <= 10000 && empNum >= 99999)
{
System.out.print ("Invalid input, please try again: ");
}
if (empNum >= 10000 && empNum <= 99999)
{
employeeNum = empNum;
}
}
public String getFirstName()
{
return firstName;
}
public String getLastName()
{
return lastName;
}
public char checkGender(char g)
{
if (g != 'M' || g != 'F')
{
g = 'F';
}
return g;
}
public char getGender()
{
return gender;
}
#Override
public boolean equals(Object e2)
{
if (this.employeeNum == ((Employee)e2).employeeNum)
{
return true;
}
else
{
return false;
}
}
#Override
public String toString()
{
return employeeNum + "\n" + lastName + ", " + firstName + "\n" + "Gender:" + gender + "\n" + "Status:" + fulltime + "\n";
}
public abstract double calculateWeeklyPay();
public abstract void annualRaise();
public abstract double holidayBonus();
public abstract void resetWeek();
}
I honestly have no idea what I am doing wrong, if someone could point me in the right direction I would really appreciate it. Thank you!
Local declaration of
Employee[] employees = new Employee[employeeMax];
hides the instance variable, try with:
employees = new Employee[employeeMax];
otherwise the employees you are instantiating is a local variable which disappears after the call to the constructor.
In your situation you have
Employees[] e = NULL;
method()
{
Employees[] e = new Employees[N]; // this declares a different variable with same name
}
method2()
{
.. e[0] .. // exception: e was still NULL
}

Categories

Resources