Abstract Class Java Why is my program only printing 0.00? - java

Abstract Class Java Why is my program only printing 0.00?
public class TestEmployee
{
public static void main(String[] args)
{
Employee[] folks = new Employee[4];
folks[0] = new SalariedEmployee("Suzy",123,520000.00);
folks[1] = new WageEmployee("Fred",456,7.50,40);
folks[2] = new SalariedEmployee("Harry",234,45000.00);
folks[3] = new WageEmployee("Rita",345,7.76,38);
for(int i=0; i<folks.length; i++)
{
System.out.println(folks[i].getName()
+ " earns " + folks[i].getMonthlyPay() + " each month");
}
}
}
I added the missing classes needed to make
the program compile and run properly
abstract class Employee
{
private String name;
private int number;
public abstract double getMonthlyPay();
public Employee(String name, int number, double salary)
{
setName(name);
setNumber(number);
salary = getMonthlyPay();
}
public Employee(String name, int number, double salary, int hours)
{
setName(name);
setNumber(number);
salary = getMonthlyPay();
}
public String getName()
{
return this.name;
}
public int getNumber()
{
return this.number;
}
public String setName(String name)
{
this.name = name;
return this.name;
}
public int setNumber(int number)
{
this.number = number;
return this.number;
}
}
Please provide an explanation or insight as to why my program is only printing zeroes. I think this is where my problem lies
class SalariedEmployee extends Employee
{
private double yearSalary;
public SalariedEmployee(String name, int number, double salary)
{
super(name, number, salary);
yearSalary = getMonthlyPay();
}
public double getMonthlyPay()
{
double monthlyPay = yearSalary / 12;
return monthlyPay;
}
public String toString()
{
return(super.getName() + ", " + super.getNumber() + ", " + getMonthlyPay());
}
}
class WageEmployee extends Employee
{
private double wage;
private int hours;
public WageEmployee(String name, int number, double salary, int hours)
{
super(name, number, salary, hours);
}
public double getMonthlyPay()
{
double monthlyPay = wage * hours * 4;
return monthlyPay;
}
public String toString()
{
return(super.getName() + ", " + super.getNumber() + ", " + getMonthlyPay());
}
}

It’s not too difficult to track back to where the 0.00 comes from.
In you for loop in main you use folks[i].getMonthlyPay() to get the number to print. So let’s look into the implementations of getMonthlyPay(). There are two implementations, one in SalariedEmployee and one in WageEmployee.
In case of a SalariedEmployee the getMonthlyPay method uses the value of the field yearSalary. Which value is assigned to yearSalary? Have you editor or IDE find all the occurrences of yearSalary to see where a value is assigned to it. You will see that it happens nowhere. Since yearSalary is a field (more precisely, an instance variable), Java assigns 0.00 to it from the start (local varaibles inside a method are different). Since you never assign any other value, the value is still 0.00 when getMonthlyPay() divides it by 12 and returns the result. So this is where 0.00 comes from. Can you find a way to fix it?
In case of a WageEmployee — you should try the same exercise yourself, find out where the value comes from in WageEmployee.getMonthlyPay(). This time you will need to find out both where the value of wage and where the value of hours come from. Happy searching.

Related

JAVA Get & Set methods with calculations

new to Java and trying to set up get and set methods. Although one I need to do as calculation based off getSalary() multiplied by getMonths() to get a Year to Date total.
I haven't been able to find out if calculations are possible in get or set methods or I may just be such a newbie I have it in the wrong place.
public class Employee_v2
{
//Instance variables
private String first_name;
private String last_name;
private double salary;
private int months;
final double increase= 0.25;
private double year_to_date;
public Employee_v2()
{
//fill in the code to set default values to the instance variables
first_name="";
last_name="";
salary= 0.0;
months= 0;
}
//Constructor initializing instance variables with arguments
public Employee_v2(String f, String l, Double sal, int mo)
{
first_name = f;
last_name = l;
salary = sal;
months = mo;
}
//set arguments
public void setFirst(String f)
{
first_name = f;
}
public void setLast (String l)
{
last_name = l;
}
public void setSalary (double sal)
{
salary = sal;
}
public void setMonths (int mo)
{
months = mo;
}
public void setYtdSalary ()
{
double yearToDateSal;
yearToDateSal = getSalary() * getMonths();
}
//get arguments
public String getFirst()
{
return first_name;
}
public String getLast()
{
return last_name;
}
public double getSalary()
{
return salary;
}
public int getMonths()
{
return months;
}
public double getYtdSalary()
{
return yearToDateSal;
}
//DISPLAY
public void displayEmployee()
{
//display the name and salary of both Employee objects
System.out.println("Employee first name: " + getFirst());
System.out.println("Employee last name: " + getLast());
System.out.printf("Employee salary: $%.2f\n", getSalary());
//complete the code
System.out.println("-------------------------------");
//Determine the year to date salary for both employee
System.out.printf(getFirst() + "'s salary: $%.2f\n", getSalary());
// System.out.println(jas.getSalary());
System.out.printf("Year to date salary: $%.2f\n", getYtdSalary());
//set and display salary with increase
setSalary(getSalary()+ getSalary()*increase);
System.out.printf("New Salary: $%.2f\n", getSalary());
System.out.println();
System.out.println();
}//end method
}//end Class
Calculation are possible in getter and setter. I would do something like this:
public double getYtdSalary(){
double ytd = 0;
ytd = months * salary;
return ytd;
}
Like this you can calculate the year to date on the fly and is always accurate data. For example if you called the setMonths method you would also have to call the setYtdSalary before calling the getYtdSalary.
Also there is no need to call your getters in your class to access your private variables.
I would also suggest using Javadoc comment in your classes as they make it easier to understand what the methods do.
to answer your question: yes it is possible to do calculations
this is also needed in many places, as the main reason to use get and set methods is so you can check or manipulate the values before setting them in your class
I guess your Code will Crash on the printing of the year to date Salary, because the variable yearToDateSal is only valid in the Scope of your set Method.
public void setYtdSalary ()
{
double yearToDateSal;
yearToDateSal = getSalary() * getMonths();
}
you should declare your YearToDateSal variable in the beginning of the class, i.e. rigth after
final double increase= 0.25;
private double year_to_date;
private double yearToDateSal;
and in your setYtdSalary() remove the declaration of yearToDateSal;
this way you should be fine :)

Setters & Getters returning 0 value

For some reason when I input values for RTH and CTH I receive 0.0 values. I had a similar issue on my shift getters, but I managed to fix that. Unfortunately, attempting to reverse engineer the problem hasn't helped. I've provided the code for my class and my driver, although I am almost convinced the issue is somewhere in the class. Nevertheless, can anyone take a quick look at the RTH / CTH setters/ getters and see what I've done wrong in setting or calling them.
public class TeamLeader extends ProductionWorker
{
//private variables
private double RTH;
private double CTH;
private double payRate;
private double monthlyBonus;
//constructor
public TeamLeader(String name, String number, String hd, int shift,
double rate, double monthlyBonus, double RTH, double CTH)
{
super(name, number, hd, shift, rate);
this.monthlyBonus = monthlyBonus;
}
public void setmonthlyBonus(double monthlyBonus)
{
this.monthlyBonus = monthlyBonus;
}
public void setpayRate(double payRate)
{
this.payRate = payRate;
}
public void setRTH(double r)
{
RTH = r;
}
public void setCTH(double c)
{
CTH = c;
}
//Getters
public double getmonthlyBonus()
{
return monthlyBonus;
}
public double getpayRate()
{
return payRate;
}
public double getRTH()
{
return RTH;
}
public double getCTH()
{
return CTH;
}
}
Driver
public class WorkDriver {
public static void main(String[] args) {
String name;
String number;
String hireDate;
int shift;
double payRate;
double monthlyBonus;
double RTH;
double CTH;
name = JOptionPane.showInputDialog("Enter your name");
number = JOptionPane.showInputDialog
("Enter your number (Format: XXX-L)");
hireDate = JOptionPane.showInputDialog("Enter your hire date");
shift = Integer.parseInt(JOptionPane.showInputDialog
("Please enter the work shift for the employee:\n"
+ "\tEnter 1 for the day shift"
+ "\n\tEnter 2 for the night shift"));
payRate = Double.parseDouble(JOptionPane.showInputDialog
("Enter your pay rate"));
monthlyBonus = Double.parseDouble(JOptionPane.showInputDialog
("Enter your monthly bonus"));
RTH = Double.parseDouble(JOptionPane.showInputDialog
("Enter your required traing hours"));
CTH = Double.parseDouble(JOptionPane.showInputDialog
("Enter your training hours attended"));
//Production worker object
TeamLeader driver = new TeamLeader(name, number,
hireDate, shift, payRate, monthlyBonus, RTH, CTH);
JOptionPane.showMessageDialog(null,
"----------- Employe Info ----------------"
+ "\nName: " + driver.getName()
+ "\nEmployee Number: " + driver.getNumber()
+ "\nHire Date: " + driver.getHireDate()
+ "\nPay Rate: " + driver.getPayRate()
+ "\nShift: " + driver.getShift()
+ "\nMonthly Bonus: " + driver.getmonthlyBonus()
+ "\nRequired Training Hours: " + driver.getRTH()
+ "\nTraining Hours Attended: " + driver.getCTH());
System.exit(0);
}
}
You never call the setters of CTH and RTH. You pass their values to your constructor but don't use them.
Add to your constructor setting of CTH and RTH :
public TeamLeader(String name, String number, String hd, int shift,
double rate, double monthlyBonus, double RTH, double CTH)
{
super(name, number, hd, shift, rate);
this.monthlyBonus = monthlyBonus;
this.RTH = RTH;
this.CTH = CTH;
}
You're calling the parent (super) constructor, but it doesn't take RTH or CTH, and you never set RTH and CTH on your TeamLeader object.
public TeamLeader(String name, String number, String hd, int shift,
double rate, double monthlyBonus, double RTH, double CTH)
{
super(name, number, hd, shift, rate);
this.monthlyBonus = monthlyBonus;
this.RTH = RTH;
this.CTH = CTH;
}
You are not setting the passed RTH to the instance's RTH. See code above for the fix

Creating a car class in java

Okay, I need to write code that makes this file
public class HW1tester
{
public static void main(String[] args)
{
Car car1 = new Car();
Car car2 = new Car("Ford", 2013, 20000);
Car car3 = new Car("Audi", 2012, 25000);
Car car4 = new Car();
car2.setPrice(22000);
car2.setYear(2011);
car4.setBrand("Cadillac");
System.out.println("This car is " + car1.getBrand() + ", year " + car1.getYear() + ", price " + car1.getPrice());
System.out.println("This car is " + car2.getBrand() + ", year " + car2.getYear() + ", price " + car2.getPrice());
System.out.println("This car is " + car3.getBrand() + ", year " + car3.getYear() + ", price " + car3.getPrice());
System.out.println("This car is " + car4.getBrand() + ", year " + car4.getYear() + ", price " + car4.getPrice());
System.out.println("The total car number is: " + car1.getNumber());
System.out.println("The total car number is: " + car2.getNumber());
System.out.println("The total car number is: " + car3.getNumber());
System.out.println("The total car number is: " + car4.getNumber());
}
}
So far I have this, but I'm not sure what the hell I'm doing wrong.
public class Car
{
private int yearModel;
private String brand;
private int priceModel;
private int numberModel;
public Car(String b, int year, int price, int number)
{
yearModel = year;
brand = b;
priceModel = price;
numberModel = number;
}
public int getYear()
{
return yearModel;
}
public String getBrand()
{
return brand;
}
public int getPrice()
{
return priceModel;
}
public int getNumber()
{
return numberModel;
}
public void setYear(int year)
{
yearModel = year;
}
public void setBrand(String carBrand)
{
brand = carBrand;
}
public void setPrice(int price)
{
priceModel = price;
public void setNumber(int number)
{
numberModel = number;
}
}
Everytime I run the first code right now it just gives me errors on car1, car2, etc I just can't seem to see what I'm doing wrong at all, I hope somebody can help me out. By the way, I can't make ANY changes to HW1tester.
When creating a new object (car1, car2, etc.), you're not passing in enough variables. Your constructor requires 4 and you're giving, at most, 3 variables when trying to construct a new car object.
You have created parameterized Constructor i.e. public Car(String b, int year, int price, int number)
So when you are trying to create object for the same like, Car car1 = new Car(); then it won't be possible. Because in this you are trying to call default constructor. Which is not present in the class.
While creating object you need to pass 4 arguments.
Moreover, in Car car2 = new Car("Ford", 2013, 20000); You are passing 3 arguments which doesn't match with the constructor.
To create object of class Car, you need to do something like,
Car c = new Car('Volvo', 2014, 25000, 1234);
you need to write overloaded constructors with different parameter sets.
when you call new Car(), java is looking for a ctor with no params, new Car("audi", 2013, 25000) one with 3 params etc.
in your Car.java file:
public Car() {}
then you can set the instance variables with their getters and setters (until you do, their values will be null).
if you want, you can define more, but their signatures have to be different. eg:
public Car(String b, int year) { ... } and public Car(String b, int price) {...} wont work, because they have the same signature.
In class Car, you have a constructor that has 4 parameters. However in the main class, you create a Car with 0 or 3 parameters. In other to run the code, you have to add 2 more constructor, one with 0 parameter, and one with 3 parameters.
public Car() {
}
public Car(String b, int year, int price) {
yearModel = year;
brand = b;
priceModel = price;
}
public Car() {
}
public Car(String b, int year, int price,) {
yearModel = year;
brand = b;
priceModel = price;
}
In that case you have a constructor that has 4 parameters.

Array of Student objects java

Just to give a run down of what I am trying to do, here is the HW my professor gave me:
Define a class Student which extends Person. It adds the attributes
Int Test1, test2, test3
Double average
String grade
It has methods computeaverage() and calculategrade(). The grades are based on the average, with above 90 an A, 80 to 90 a B, 70 to 80 a C etc. All other attributes have a set and a get.
Write an application that uses an array of type student of size 20. The program prompts the user for how many students are in the class and then allows them to enter the students and their test scores, then calculates their grades and prints out the list of students and their grades.
That being said...
On Thursday I saw a classmates code that he got from the teacher and he had something that I haven't seen before in my student class on line 37 (Student Constructor). Instead of having getters and setters he had code similar to what I have at line 37. But I have no idea what he did and the correct coding. So I was hoping someone here could tell me what I am doing wrong and how this code can get away without using getter and setter methods???
public class Person {
/**
* #param args the command line arguments
*/
public static void main(String[] args)
{
Scanner kbd = new Scanner(System.in);
Student newStudent = new Student();
int size;
System.out.println("Enter the amount of students:");
size = kbd.nextInt();
Student[] myStudent = new Student[size];
String firstName;
String lastName;
int test1, test2, test3;
Student s;
for (int i=0; i < size; i++)
{
System.out.println("Enter first name of student: " + i);
firstName = kbd.next();
System.out.println("Enter last name if student: " +i);
lastName = kbd.next();
System.out.println("Please Enter first test score: ");
// JOptionPane.showInputDialog("Please enter first test score:");
test1= kbd.nextInt();
System.out.println("Please enter second test score");
// JOptionPane.showInputDialog("Please enter second test score:");
test2= kbd.nextInt();
System.out.println("Please enter third test score");
// JOptionPane.showInputDialog("Please enter third test score:");
test3=kbd.nextInt();
// s = new Student (test1, test2, test3, firstName, lastName);
myStudent[i].setTest1(test1);
myStudent[i].setTest2(test2);
myStudent[i].setTest3(test3);
myStudent[i].setfName(fName);
myStudent[i].setlName(lname);
}
for (int i = 0; i < size; i++)
{
System.out.println(myStudent[i].getGrade());
}
}
}
public class Student extends Person{
int test1, test2, test3;
double average;
String grade, firstName, lastName;
public Student()
{
test1 = 0;
test2 = 0;
test3 = 0;
average = 0;
}
public Student(int test1, int test2, int test3, String firstName, String lastName)
{
this.test1 = test1;
this.test2 = test2;
this.test3 = test3;
this.setfirstName = firstName;
}
public double computeAverage()
{
average = (test1 + test2 + test3)/3;
return average;
}
public String calculateGrade()
{
average = computeAverage();
if (average < 60){
grade = "F";}
else if (average < 70){
grade = "D";}
else if (average < 80){
grade = "C";}
else if (average < 90){
grade = "B";}
else {
grade = "A";
}
return grade;
}
public int getTest1() {
return test1;
}
public void setTest1(int test1) {
this.test1 = test1;
}
public int getTest2() {
return test2;
}
public void setTest2(int test2) {
this.test2 = test2;
}
public int getTest3() {
return test3;
}
public void setTest3(int test3) {
this.test3 = test3;
}
public double getAverage() {
return average;
}
public void setAverage(double average) {
this.average = average;
}
public String getGrade() {
return grade;
}
public void setGrade(String grade) {
this.grade = grade;
}
}
Your Person class is wrong. It has no attributes or methods. There's no reason to extend it, because it brings nothing to the party.
You don't need getters or setters if the attribute is visible to the public, but that doesn't mean it's a good idea.
Try thinking more like this:
public class Person {
protected String firstName;
protected String lastName;
public Person(String f, String l) {
this.firstName = f;
this.lastName = l;
}
public String getFirstName() { return this.firstName; }
public String getLastName() { return this.lastName; }
}
public class Student extends Person {
public static final int MAX_GRADES = 3;
private int numGrades = 0;
private int maxGrades;
private int [] grades;
public Student(String f, String l) {
this(f, l, MAX_GRADES);
}
public Student(String f, String l, int maxGrades) {
super(f, l);
this.maxGrades = (maxGrades > 0) ? maxGrades : MAX_GRADES;
this.grades = new int[this.maxGrades];
}
public void addGrade(int grade) {
if (this.numGrades < this.maxGrades) {
this.grades[numGrades++] = grade;
}
}
public double getAverageGrade() {
double average = 0.0;
if (this.numGrades > 0) {
for (int i = 0; i < this.numGrades; ++i) {
average += grade[i];
}
average /= this.numGrades;
}
return average;
}
}
There are two constructors in Studentclass:
Constructor without parameters
Constructor with paramers (int,int,int,String,String)
This is called method/function overloading. You can declare many method with the same name, but the signature has to change. In other words, it has to have different parameters (so the compiler will know which version of the method to use).
So you have one constructor without parameters, that just set test1, test2, test3 and average to 0. And you have this constructor:
public Student(int test1, int test2, int test3, String firstName, String lastName)
{
this.test1 = test1;
this.test2 = test2;
this.test3 = test3;
...
}
that receives 4 parameters and assigns them to the respective fields.
Note that you should initialize average in the constructor too, as well as set firstName and lastName:
this.average = 0; // Or maybe 'this.average = computeAverage();'
this.firstName = firstName;
this.lastName = lastName;
Typically, you'll want to encapsulate your fields as much as possible. This means make these
int test1, test2, test3;
double average;
String grade, firstName, lastName;
things private. You'll then need getters and setters to access them from outside the class. That's a good thing. However, from inside the class, you can use them without getters or setters no problem.
Does this answer your question? I have no idea what is on line 37, as you didn't provide numbering. :)
Edit: In case you don't know, constructors can be overloaded. You have two different constructors, one with parameters, one without. You can choose which one you want to use to construct the class, you probably want to be using the second one.
If you have need for both constructors, one complete one and another one that uses default values, you might want to contemplate referencing the second constructor from inside the first, to avoid duplication of code. Like so:
public Student() {
this(0,0,0);
}
public Student(int test1, int test2, int test3, String firstName, String lastName) {
this.test1 = test1;
this.test2 = test2;
this.test3 = test3;
this.average = 0;
this.firstName = firstName;
this.lastName = lastName;
}
His instance variables (the variables declared at the beginning of Student) were public, which allowed him to access and change them directly without the use of setters and getters. Normally, these variables are private, requiring methods to access/change them.

Need some help in Java Inheritance! (In LuxuryCarRental int days is always coming as 0)

Create a class named CarRental that contains fields that hold a renter’s name, zip code, size of the car rented, daily rental fee, length of rental in days, and total rental fee. The class contains a constructor that requires all the rental data accept the daily rate and total fee, which are calculated, based on the size of the car: economy at $29.99 per day, midsize at $38.99 per day, or full size at $43.50 per day. The class also includes a display() method that displays all the rental data.
Create a subclass named LuxuryCarRental. This class sets the rental fee at $79.99 per day and prompts the user to respond to the option of including a chauffeur at $200 more per day. Override the parent class display() method to include chauffeur fee information. Write an application named UseCarRental that prompts the user for the data needed for a rental and creates an object of the correct type. Display the total rental fee.
Save the files as CarRental. java, LuxuryCarRental. java, and UseCarRental. java
public class CarRental
{
String name;
int zip;
String size;
double dailyFee;
int days;
double total;
public CarRental(String size)
{
if(size.charAt(0)=='e')
dailyFee = 29.99;
else if(size.charAt(0)=='m')
dailyFee = 38.99;
else
dailyFee =43.50;
}
public String getname()
{
return name;
}
public int getzip()
{
return zip;
}
public String getsize()
{
return size;
}
public int getdays()
{
return days;
}
public void computetotal(int days)
{
total = dailyFee*days;
}
public void print()
{
System.out.println("The cost of your rental car is $" + total);
}
}
public class LuxuryCarRental extends CarRental
{
public LuxuryCarRental(String size, int days)
{
super(size);
}
public void computetotal1()
{
super.computetotal(days);
dailyFee = 79.99;
total = dailyFee;
System.out.println(days); //trying to see if days still 0
}
}
import javax.swing.*;
import java.util.Scanner;
public class UseCarRental
{
public static void main(String args[]) throws Exception
{
int days;
String name;
int zip;
String size;
Scanner inputDevice = new Scanner(System.in);
System.out.println("Enter days: ");
days= inputDevice.nextInt();
System.out.println("Enter name: ");
name = inputDevice.next();
System.out.println("Enter zip: ");
zip = inputDevice.nextInt();
System.out.println("Enter size: ");
size = inputDevice.next();
CarRental econ = new CarRental(size);
econ.computetotal(days);
econ.print();
CarPhone full = new CarPhone(size, days);
full.computetotal1();
full.print();
}
}
You're not doing anything with days in LuxuryCarRental, your constructor takes it as an argument but does nothing with it. Ideally it should be passed to the CarRental object constructor but in any case, add
this.days = days;
to LuxuryCarRental constructor, or better your CarRental constructor with a new argument.
There is no need to rename your computetotal method either,leave it with the same name; it the child object will override the implementation details from its parent. Look in to polymorphism: http://en.wikipedia.org/wiki/Polymorphism_in_object-oriented_programming
Also, indent your code to make it more readable http://en.wikipedia.org/wiki/Indent_style
You're not initializing days anywhere in both the classes, that's why getdays is returning 0. Please initialize days, before accessing it.
In constructor of CarRental class, make days as an argument, like this:
public CarRental(String size, int days)
{
if(size.charAt(0)=='e')
dailyFee = 29.99;
else if(size.charAt(0)=='m')
dailyFee = 38.99;
else
dailyFee =43.50;
this.days = days;
}
In LuxuryCarRental's constructor, do this:
public LuxuryCarRental(String size, int days)
{
super(size, days);
}

Categories

Resources