Inheritance & Polymorphism in Java - java

I have programmed for exercising the Inheritance & Polymorphism use in Java, but coming across some problems, please see the codes below:
Superclass:
public class Worker {
private String name;
private double salaryRate;
public Worker(String nm, double rate){
nm=name;
rate=salaryRate;
}
public void computePay(int hours){
double pay=hours*salaryRate;
System.out.println("The Salary for "+getName()+" is "+pay);
}
public String toString(){
return name+" "+salaryRate;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getSalaryRate() {
return salaryRate;
}
public void setSalaryRate(double salaryRate) {
this.salaryRate = salaryRate;
}
}
one subclass:
public class HourlyWorker extends Worker {
public HourlyWorker(String nm, double rate) {
super(nm, rate);
}
public void computePay(int hours){
if (hours>40){
double extraPay=(hours-40)*1.5*getSalaryRate();
double pay=40*getSalaryRate();
double total=extraPay+pay;
System.out.println("The salary for "+getName()+" is "+total);
}
else{
super.computePay(hours);
}
}
}
Another subclass:
public class SalariedWorker extends Worker {
public SalariedWorker(String nm, double rate){
super(nm,rate);
}
public void computePay(int hours){
double pay=40*getSalaryRate();
System.out.println("The salary for "+getName()+" is "+pay);
}
}
Main() method:
public class Test {
public static void main(String[] args) {
Worker a=new HourlyWorker("Tom",2.0);
Worker b=new HourlyWorker("Lee",2.0);
Worker c=new SalariedWorker("Pei",2.0);
Worker d=new SalariedWorker("Joe",2.0);
System.out.println(a+" "+b+" "+c+" "+" "+d);
a.computePay(50);
b.computePay(30);
c.computePay(20);
d.computePay(60);
}
}
It is a bit long, thank you for your patient to read:)
However, when they compile, it shows:
null 0.0 null 0.0 null 0.0 null 0.0
The salary for null is 0.0
The Salary for null is 0.0
The salary for null is 0.0
The salary for null is 0.0
Please advise where goes wrong, thank you guys!

You assignments are reversed in the constructor. You are not setting the instance attributes values using the input params and hence those attributes always have the default values.Change this
public Worker(String nm, double rate){
nm=name;
rate=salaryRate;
}
to
public Worker(String nm, double rate){
this.name=nm;
this.salaryRate=rate;
}
Note: Usage of this helps you to avoid shadowing problems as well when the name of the input params and class attributes are same.

public Worker(String nm, double rate){
nm=name;
rate=salaryRate;
}
you are assigning values to local variables not to the instance variables.
Therefore those variables are having their default values.
for string default value is null
for double it is 0.0
you should do
public Worker(String nm, double rate){
name = nm;
salaryRate = rate;
}

Related

Employee Salary Calculation

Task Description
I have this problem statement:
Create a class Employee with the following private member variables.
int employeeId
String employeeName
double salary
double netSalary
Include appropriate getters and setters method in Employee class. Write the following method in the Employee class:
public void calculateNetSalary(int pfpercentage) - This method should take PF percentage as argument. Deduct the PF amount from the salary and set the netSalary.
Create a Main class which has the main method which invokes the method to get the input and prints the details as shown in the sample.
Also write a method :
public static Employee getEmployeeDetails() - which gets the employee details - id, name and salary, and returns the employee object.
public static int getPFPercentage() - which gets the PF percentage and returns the same
In the main method invoke the above two methods, and then call the calculateNetSalary method in Employee class and print the output as shown below.
Sample Input 1:
Enter Id:
101
Enter Name:
Vivek
Enter salary:
20000
Enter PF percentage:
7
Sample Output 1:
Id : 101
Name : Vivek
Salary : 20000.0
Net Salary : 18600.0
What I have done
I wrote the getter & setters methods and calculateNetSalary() method in Employee.java. I am stuck in as what and how should I write in Main.java
Employee.java
public class Employee{
private int employeeId;
private String employeeName;
private double salary;
private double netSalary;
//setters
public void setEmployeeId(int employeeId){
this.employeeId=employeeId;
}
public void setEmployeeName(String employeeName){
this.employeeName=employeeName;
}
public void setSalary(double salary){
this.salary=salary;
}
public void netSalary(double netSalary){
this.netSalary=netSalary;
}
//getters
public int getEmployeeId(){
return employeeId;
}
public String getEmployeeName(){
return employeeName;
}
public double getSalary(){
return salary;
}
public double getNetSalary(){
return netSalary;
}
public void calculateNetSalary(int pfpercentage){
pfamount=salary*pfpercentage;
netSalary=salary-pfamount;
}
}
Main.java
import java.util.Scanner;
public class Main{
public staic void main(String[] args){
Scanner sc = new Scanner(System.in);
Employee emp = new Employee();
System.out.println("Enter Id:"+setEmployeeId(sc.nextInt()))
System.out.println("Enter Name:"+setEmployeeName(sc.next()));
System.out.println("Enter salary:"+setSalary(sc.nextDouble()));
System.out.println("Enter PF percentage:");
double pfpercentage = sc.nextDouble();
public static Employee getEmployeeDetails(){
}
public static int getPFPercentage(){
}
}
}
I am unable to complete Main.java as I am not sure what and how to write.
This should be your code:
public void main(String[] args){
Scanner sc = new Scanner(System.in);
Employee emp = new Employee();
emp.setEmployeeId(sc.nextInt());
emp.setEmployeeName(sc.next()) ;
emp.setSalary(sc.nextDouble());
System.out.println("Enter PF percentage:");
double pfpercentage = sc.nextDouble();
emp.calculateNetSalary(pfpercentage);
System.out.println("Salay is " + emp.getNetSalary());
}
Also please notice that you haven't defined the type of pfamount:
public void calculateNetSalary(double pfpercentage){
double pfamount=salary*pfpercentage;
netSalary=salary-pfamount;
}
You can't define another methods inside the main() method.
You can call other methods inside it (as much as you like).
You have a couple of issues in your code. Firstly looking at Employee.java, there are a couple of issues:
Your method to set netSalary is declared as public void netSalary(double netSalary), where it should rather be public void SetNetSalary(double netSalary)
The calculation in public void calculateNetSalary(int pfpercentage) looks incorrect. If you going to pass in a double (i.e. 2 to represent 2%) then you need to divide this by 100 to convert the number to percentage.
You need to declare variables if you going to use them (namelty pfamount needs to be declared as a double before you can assign something to it).
You'll probably need a public String toString() method, for printing out your employee object.
So you'll end up with something like this:
public class Employee{
private int employeeId;
private String employeeName;
private double salary;
private double netSalary;
//setters
public void setEmployeeId(int employeeId){
this.employeeId=employeeId;
}
public void setEmployeeName(String employeeName){
this.employeeName=employeeName;
}
public void setSalary(double salary){
this.salary=salary;
}
public void setNetSalary(double netSalary){
this.netSalary=netSalary;
}
//getters
public int getEmployeeId(){
return employeeId;
}
public String getEmployeeName(){
return employeeName;
}
public double getSalary(){
return salary;
}
public double getNetSalary(){
return netSalary;
}
public void calculateNetSalary(double pfpercentage) {
double pfamount = salary * (pfpercentage / 100);
netSalary = salary - pfamount;
}
#Override
public String toString() {
String output = new StringBuffer()
.append("Id: ").append(employeeId)
.append(System.lineSeparator()).append("Name: ").append(employeeName)
.append(System.lineSeparator()).append("Salary: ").append(salary)
.append(System.lineSeparator()).append("Net Salary: ").append(netSalary).toString();
return output;
}
}
The you also have a couple of issues with your Main.java:
You can't declare methods within methods.
This is not the correct way to implement java.util.Scanner ... System.out.println("Enter Id:"+setEmployeeId(sc.nextInt())). Essentially the Scanner portion needs to be separated from the System.out (remember the only thing System.out does is print out text, it does not wait for input from Scanner).
If I understand your question correctly, you need to move some of your logic out of your main method and into getEmployeeDetails() and getPFPercentage()
So you'll end up with something like this:
import java.util.Scanner;
public class EmployeeSalaryCalculation {
private Scanner scanner;
public EmployeeSalaryCalculation() {
scanner = new Scanner(System.in);
}
public Employee getEmployeeDetails() {
Employee employee = new Employee();
System.out.println("Enter Id:");
employee.setEmployeeId(scanner.nextInt());
System.out.println("Enter Name:");
employee.setEmployeeName(scanner.next());
System.out.println("Enter salary:");
employee.setSalary(scanner.nextDouble());
return employee;
}
public double getPFPercentage(){
System.out.println("Enter PF percentage:");
return scanner.nextDouble();
}
public static void main(String[] args) {
EmployeeSalaryCalculation employeeSalaryCalculation = new EmployeeSalaryCalculation();
Employee employee = employeeSalaryCalculation.getEmployeeDetails();
employee.calculateNetSalary(employeeSalaryCalculation.getPFPercentage());
System.out.println(employee.toString());
}
}
You've made a good start. However, there are a couple of syntax errors such as forgetting to end some statements with a semi-colon. Also, as far as I know, Java doesn't support nested methods, so you shouldn't have the methods getEmployeeDetails() and getPFPercentage() inside your main method. I have rearranged the code to correct that.
Other changes I made was to your Employee class, particularly the calculateNetSalary method. pfPercentage is divided by 100 before multiplication by salary. Also, the instance variable netSalary is set to be the local variable netSalary after it has been calculated using the appropriate setter method. The method netSalary has also been renamed to setNetSalary since that is more descriptive of what the method does.
I haven't made any other changes to your code other than completing the Main class according to specifications. If there's any other part of the code that needs clarification, you can leave a comment about that.
Main.java
import java.util.Scanner;
public class Main {
private static Scanner scanner = new Scanner(System.in);
public static void main(String[] args){
Employee newEmployee = getEmployeeDetails();
double pfPercentage = getPFPercentage();
System.out.println();
System.out.println("Confirm employee details: ");
System.out.println("Id : " + newEmployee.getEmployeeId());
System.out.println("Name : " + newEmployee.getEmployeeName());
System.out.println("Salary : " + newEmployee.getSalary());
newEmployee.calculateNetSalary(pfPercentage);
System.out.println("Net Salary : " + newEmployee.getNetSalary());
}
/**
* Gets the details of a new employee from user input
* #return the new {#link Employee}
*/
public static Employee getEmployeeDetails() {
Employee employee = new Employee();
System.out.println("Enter Id: ");
employee.setEmployeeId(scanner.nextInt());
System.out.println("Enter Name: ");
employee.setEmployeeName(scanner.next());
System.out.println("Enter salary: ");
employee.setSalary(scanner.nextDouble());
return employee;
}
/**
* Gets the PF percentage from user input
* #return the PF percentage
*/
public static double getPFPercentage(){
System.out.println("Enter PF percentage:");
double pfPercentage = scanner.nextDouble();
return pfPercentage;
}
}
Employee.java
public class Employee{
private int employeeId;
private String employeeName;
private double salary;
private double netSalary;
// Setters
public void setEmployeeId(int employeeId){
this.employeeId = employeeId;
}
public void setEmployeeName(String employeeName){
this.employeeName = employeeName;
}
public void setSalary(double salary){
this.salary = salary;
}
private void setNetSalary(double netSalary){
this.netSalary = netSalary;
}
// Getters
public int getEmployeeId(){
return employeeId;
}
public String getEmployeeName(){
return employeeName;
}
public double getSalary(){
return salary;
}
public double getNetSalary(){
return netSalary;
}
public void calculateNetSalary (double pfPercentage){
double pfAmount = salary * (pfPercentage / 100);
double netSalary = salary - pfAmount;
this.setNetSalary(netSalary);
}
}
Write a class, Manager, that extends MonthlyEmployee, and has another instance variables, bonus and an instance method, setBonus. Override the pay method and update TestEmployee accordinly.
3.Write a class, TestShapes, that creates an instance of each of our shape classes and prints it.

Implementing different predicates for different types of employees

I'm new to using predicates and not sure if I'm understanding it properly. I have an abstract employee class in which hourly and salary employee's are created separately. My issue relies in my EmployeePredicate.java class where I am unsure how to check whether it is an hourly employee and to return true or false.
I need to create a different predicate for all of the following conditions:
All employees, Hourly Only, Salary Only and Fulltime Only.
So far I am only trying to get the "Hourly Only" Predicate to work properly first and think I could figure out the rest after that. I am unsure what to put after the 'p' to check which type of employee it is. What I have currently is:
public static Predicate<Employee> isHourlyEmployee() {
return p -> p.
}
I also have the statement double avgSalary = calculateAveragePay(employees, null); and am unsure what to replace null with as it should be a predicate based off my calculateAveragePay function above in main.
Main.java
package homework04;
import java.util.function.Predicate;
public class Main {
public static double calculateAveragePay(Employee[] employees, Predicate<Employee> pred) {
double sum = 0.0;
int count = 0;
for(Employee e : employees) {
if(!pred.test(e)) {
continue;
}
sum += e.calculatePay();
count++;
}
return sum / count;
}
public static void main(String[] args) {
//The list of employees to calculate.
Employee[] employees = {
new HourlyEmployee("John Smith", 80, 18.00),
new HourlyEmployee("Jane Doe", 77, 20.00),
new SalaryEmployee("Bob Miller", 85, 40000.00),
new HourlyEmployee("Alice Davis", 40, 12.50),
new SalaryEmployee("Frank Frink", 70, 35000.00),
new HourlyEmployee("Chris Williams", 95, 25.00)
};
//The average pay for both types of employee.
double avgSalary = calculateAveragePay(employees, null);
double avgHourly = calculateAveragePay(employees, null);
//The bonus to be added to employee pay.
//double bonus = Math.abs(avgSalary - avgHourly);
//Print the average pay
System.out.println("===== Average Pay =====");
}
}
Employee.java
package homework04;
import java.util.function.Predicate;
abstract class Employee {
private String name;
private int hoursWorked;
public Employee(String name, int hoursWorked) {
this.name = name;
this.hoursWorked = hoursWorked;
}
public int getHoursWorked() {
return hoursWorked;
}
public String getName() {
return name;
}
public abstract double calculatePay();
}
HourlyEmployee.java
package homework04;
public class HourlyEmployee extends Employee {
private double hourlyPay;
public HourlyEmployee(String name, int hoursWorked, double hourlyPay) {
super(name, hoursWorked);
this.hourlyPay = hourlyPay;
}
#Override
public double calculatePay() {
return getHoursWorked() * hourlyPay;
}
}
SalaryEmployee.java
package homework04;
public class SalaryEmployee extends Employee {
private static final int NUM_PAY_PERIODS = 26;
private double salary;
public SalaryEmployee(String name, int hoursWorked, double salary) {
super(name, hoursWorked);
this.salary = salary;
}
#Override
public double calculatePay() {
return salary / NUM_PAY_PERIODS;
}
}
EmployeePredicate.java
package homework04;
import java.util.function.Predicate;
public class EmployeePredicate {
public static Predicate<Employee> isHourlyEmployee() {
return p -> p.
}
}
You're looking for:
return p -> p instanceof HourlyEmployee;
but I wouldn't suggest the approach of creating a predicate for each Employee type in your EmployeePredicate factory class, instead just pass in the behavior when calling the calculateAveragePay method i.e.
double avgSalary = calculateAveragePay(employees, p -> p instanceof SalaryEmployee);
double avgHourly = calculateAveragePay(employees, p -> p instanceof HourlyEmployee);
Nevertheless, if you want to proceed with your factory class of Predicate methods because you feel it provides better readability then you can do:
public class EmployeePredicate {
public static Predicate<Employee> isHourlyEmployee() {
return p -> p instanceof HourlyEmployee;
}
}
Then the method calls to calculateAveragePay become:
double avgSalary = calculateAveragePay(employees, EmployeePredicate.isSalaryEmployee()); // create the isSalaryEmployee method
double avgHourly = calculateAveragePay(employees, EmployeePredicate.isHourlyEmployee());
As an aside, you could use the stream API to perform the calculateAveragePay making it more readable.
public static double calculateAveragePay(Employee[] employees, Predicate<Employee> pred) {
return Arrays.stream(employees)
.filter(pred)
.mapToDouble(e -> e.calculatePay())
.average().orElse(0);
}

Issue with getter and setter with one common variable

I have a task with a temperature converter program. I have to use one veriable in a class what is used by two setter and two getter method.
This is the main class:
public class Main {
public static void main(String[] args) {
Homero ho = new Homero();
ho.setCelsius(0);
System.out.println(ho.getFahrenheit());
System.out.println(ho.getCelsius());
ho.setFahrenheit(212);
System.out.println(ho.getFahrenheit());
System.out.println(ho.getCelsius());
}
}
How can I say to the getters that when the main function set the first setter, the getter return with this... and in the second time return with that...
This is the Homero class:
public class Homero {
double celsius;
public void setCelsius(double celsius){
this.celsius = celsius;
}
public void setFahrenheit(double fahr){
this.celsius = fahr;
}
public double getFahrenheit(){
return (this.celsius*9)/5+32;
}
public double getCelsius(){
return (this.celsius-32)*5/9;
}
}
And this would be the proper output:
32.0
0.0
212.0
100.0
And the wrong output what I've got.
32.0
-17.77777777777778
413.6
100.0
The getter and setter for celsius does not need a conversion. Do your calculations in the getter and setter for fahrenheit:
public void setCelsius(double celsius){
this.celsius = celsius;
}
public void setFahrenheit(double fahr){
this.celsius = (fahr -32)*5/9;
}
public double getFahrenheit(){
return this.celsius*9/5+32;
}
public double getCelsius(){
return this.celsius;
}
I would suggest to reset the other value by the setters, so every time you set a value the other is also new calculated:
public static class Homero {
double celsius;
double fahrenheit;
public void setCelsius(double celsius) {
this.celsius = celsius;
this.fahrenheit = this.celsius * 1.8 + 32;
}
public void setFahrenheit(double fahr) {
this.fahrenheit = fahr;
this.celsius = (this.fahrenheit - 32) * 5 / 9;
}
public double getFahrenheit() {
return this.fahrenheit;
}
public double getCelsius() {
return this.celsius;
}
}
public void setFahrenheit(double fahr){
this.celsius = fahr;
}
this is worng you should convert fahr to cel before assignement.
here :
public double getCelsius(){
return (this.celsius-32)*5/9;
}
you should return this.celcius

Exception Error in Java : How to continue?

Now, here' the problem :
How to add exceptions so that if my value is negative it would return an error.
here's my current code.
public class Account {
String name;
double balance;
public Account()
{
super();
this.name = null;
this.balance = 0;
}
public Account(String n, double b){
name = n;
balance = b;
}
}
did I do things right? so far?
edited to shorten.
1 . Create new Exception class like NegativeBalanceException
2 . Validate balance from the place where you are calling Account(String n, double b). If its -ve then throw NegativeBalanceException and right a catch block to handle it
In my opinion, this is what the exercise wants you to do:
public class Account {
/*
* If you know about private members, declare them private.
* Probably you should because the exercise asks for getter and setter.
*/
/* private */ String name;
/* private */ double balance;
public Account() {
// Useless: Java calls automatically the superclass constructor.
// super();
/*
* These are useless too, because Java initializes the class
* members to 0, false and null.
* However, this is what the exercise is asking you to do.
*/
name = null;
balance = 0;
}
public Account(String name, double balance) {
// take advantage of setters
setName(name);
setBalance(balance);
}
public void setName(String name) { this.name = name; }
public void setBalance(double balance) {
if (balance < 0)
throw new IllegalArgumentException("balance must be non-negative.");
this.balance = balance;
}
public String getName() { return name; }
public double getBalance() { return balance; }
}
You don't need to call super(); in your default constructor since you don't have superclass defined (at least I don't see that it extends something) and this method will call constructor from superclass.

Method Retrieval and Inheritance Confusion

Ok,so I am getting a lot of trouble, I am still learning Java and my book has set me a task that I find common over the net, the part that I am stuck on is...
I must create a bank account program, an account holder is given a savings account (which has an interest rate and no overdraft facility), and a checking account (which has an overfraft facility of £100 and no interest).
I am not implementing the overdraft yet and am only half way to getting the withdraw and deposit function ready but my question is with the interest, I have defined in my superclass the savings account balance and the checking account balance so when working out my interest in the savings account class I cannot reference savebalance as I have made it private. I am trying to use the set.name method but i am clearly doing it wrong....
A big smile and a thank you for any one who can help or give advice!
Superclass is as follows:
public class BankDetails
{
private String customer;
private String accountno;
private double savebalance;
private double checkbalance;
//Constructor Methods
public BankDetails(String customerIn, String accountnoIn, double savebalanceIn, double checkbalanceIn)
{
customer = customerIn;
accountno = accountnoIn;
savebalance = savebalanceIn;
checkbalance = checkbalanceIn;
}
// Get name
public String getcustomername()
{
return (customer);
}
// Get account number
public String getaccountnumber()
{
return (accountno);
}
public double getcheckbalanceamount()
{
return (checkbalance);
}
public double getsavebalanceamount()
{
return (savebalance);
}
public void savewithdraw(double savewithdrawAmountIn)
{
savebalance = savebalance - savewithdrawAmountIn;
}
public void checkwithdraw(double checkwithdrawAmountIn)
{
checkbalance = checkbalance - checkwithdrawAmountIn;
}
public void savedeposit(double savedepositAmountIn)
{
savebalance = savebalance - savedepositAmountIn;
}
public void checkdeposit(double checkdepositAmountIn)
{
checkbalance = checkbalance - checkdepositAmountIn;
}
} // End Class BankDetails
Sub Class is as follows:
import java.util.*;
public class Savings extends BankDetails
{
private String saveaccount;
private double interest;
public Savings(String customerIn, String accountnoIn, float interestIn,
String saveaccountIn, double savebalanceIn)
{
super (customerIn, accountnoIn, savebalanceIn, interestIn);
saveaccount = saveaccountIn;
interest = interestIn;
}
public String getsaveaccountno()
{
return (saveaccount);
}
public double getinterestamount()
{
return (interest);
}
public void interestamount(String[] args)
{
BankDetails.getsavebalanceamount(savebalance);
interest = (savebalance / 100) * 1.75;
}
}
Use the superclass's getSaveBalance() method to access the balance (which is suspiciously-named, since you have a savings account class, but keep the balance elsewhere).
(Currently it's getsavebalanceamount(), I assume a renaming to keep with Java conventions.)
I'd recommend using consistent CamelCase when naming your getters and setters, e.g., getInterestAmount(), getSaveAccountNo(), etc.
I recommend against commenting simple getters/setters, but if you do, use Javadoc conventions, e.g.:
/** Returns current savings account balance. */
public double getSaveBalance() { ... etc ... }
I also recommend avoid unnecessary parentheses, as currently in your getters, e.g.:
public double getSaveBalance() {
return saveBalance; // No parens required.
}
I suggest you do something like this,
interface Account{
int getAccountNumber();
float getBalance();
}
public class SavingAccount implements Account, Interest{
int accountNumber;
public int getAccountNumber(){
return accountNumber;
}
float balance;
public float getBalance(){
return balance;
}
float savingInterestRate;
public float getInterestRate(){
return savingInterestRate;
}
}
public class CheckingAccount implements Account, OverDraft{
int accountNumber;
public int getAccountNumber(){
return accountNumber;
}
float balance;
public float getBalance(){
return balance;
}
}
interface Interest{
float getInterestRate();
}
interface OverDraft{
....
}

Categories

Resources