Java - Overriding A Parent Class Method - java

I am new to Java and I am working on a project that works with calculating prices with/without employee discounts. After reading the following code could someone explain to me how I might go about changing the parent class method outputs from the child class in order to get the correct outputs for my program?
Parent Class (I am NOT allowed to edit this):
public class GroceryBill {
private Employee clerk;
private List<Item> receipt;
private double total;
private double internalDiscount;
public GroceryBill(Employee clerk) {
this.clerk = clerk;
receipt = new ArrayList<Item>();
total = 0.0;
internalDiscount = 0.0;
}
public void add(Item i) {
receipt.add(i);
total += i.getPrice();
internalDiscount += i.getDiscount();
}
public double getTotal() {
return Math.rint(total * 100) / 100.0;
}
public Employee getClerk() {
return clerk;
}
public void printReceipt() {
System.out.println(this);
}
private String valueToString(double value) {
value = Math.rint(value * 100) / 100.0;
String result = "" + Math.abs(value);
if(result.indexOf(".") == result.length() - 2) {
result += "0";
}
result = "$" + result;
return result;
}
public String receiptToString() {
String build = "items:\n";
for(int i = 0; i < receipt.size(); i++) {
build += " " + receipt.get(i);
if(i != receipt.size() - 1) {
build += "\n";
}
}
return build;
}
public String toString() {
return receiptToString() + "\ntotal: " + valueToString(total);
}
public String discountToString() {
return receiptToString() + "\nsub-total: " + valueToString(total) + "\ndiscount: " + valueToString(internalDiscount) + "\ntotal: " + valueToString(total - internalDiscount);
}
public static class Employee {
private String name;
public Employee(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
public static class Item {
private String name;
private double price;
private double discount;
public Item(String name, double price, double discount) {
this.name = name;
this.price = price;
this.discount = discount;
}
public double getPrice() {
return price;
}
public double getDiscount() {
return discount;
}
private String valueToString(double value) {
String result = "" + Math.abs(value);
if(result.indexOf(".") == result.length() - 2) {
result += "0";
}
result = "$" + result;
return result;
}
public String toString() {
return name + " " + valueToString(price) + " (-" + valueToString(discount) + ")";
}
}
}
Here is my code:
public class DiscountBill extends GroceryBill
{
private int myDiscountCount;
private double myDiscountAmount;
private double myPrice;
public DiscountBill(Employee clerk, boolean preferred)
{
super(clerk);
String name = "";
double price = 0;
double discount = 0;
Object myItem = new Item(name, price, discount);
myPrice = ((GroceryBill.Item) myItem).getPrice() - ((GroceryBill.Item) myItem).getDiscount();
GroceryBill.Item myBill = new GroceryBill.Item(name, price, discount);
myDiscountAmount = myBill.getDiscount();
if (myDiscountAmount > 0 && preferred)
{
myDiscountCount++;
}
}
/*
public double getTotal()
{
Override goes here?
}
*/
public int getDiscountCount()
{
return myDiscountCount;
}
public double getDiscountAmount()
{
return myDiscountAmount;
}
public double getDiscountPercent()
{
return (myPrice / getDiscountCount()) * 100;
}
}
Lastly, here is the expected output:
P.S. Please let me know if I need to give more/less information and ways that I can clean up this post or make it easier to understand. If my question was too broad, please ask me what you don't understand about it and I'll try my best to tell you! Thank you!

Related

How do I generate objects randomly in java?

I have an abstract class called "Student" and 2 subclasses "Graduate" and "Undergraduate", they both have the same parameters.
I want to create 10 Student objects randomly, some from the "Graduate" and some from the "Undergraduate" classes.
I want to print the displayStudent() method for all objects created, I got stuck on how to randomly generate the 10 students so they are all random of type graduates and undergraduates.
public abstract class Student {
private int ID;
private double GPA;
public Student(int ID, double GPA) {
this.ID = ID;
this.GPA = GPA;
}
public int getID() {
return ID;
}
public double getGPA() {
return GPA;
}
public abstract String getLevel();
public abstract String getStatus();
public final String displayStudent() {
return getLevel() + " ID>> " + getID() + ", GPA>> " + getGPA() + ", Status>> " + getStatus();
}
}
public class Graduate extends Student{
public Graduate(int ID, double GPA) {
super(ID, GPA);
}
#Override
public String getLevel() {
return "graduate";
}
#Override
public String getStatus() {
if( getGPA() >= 3) {
return "honor";
} else if (getGPA() >= 2 && getGPA() <= 3) {
return "good";
} else {
return "probation";
}
}
}
public class Undergraduate extends Student {
public Undergraduate(int ID, double GPA) {
super(ID, GPA);
}
#Override
public String getLevel() {
return "undergraduate";
}
#Override
public String getStatus() {
if( getGPA() >= 3) {
return "honor";
} else if (getGPA() >= 2 && getGPA() <= 3) {
return "good";
} else if( getGPA() > 0 && getGPA() < 2) {
return "probation";
} else {
//for any number that is not in the range of the GPA
return "invalid GPA!";
}
}
}
Try this.
using the ternary operator ?: is key.
exp ? a : b says if exp is true, do a, else do b
I used the loop index+1 as the id.
If the boolean is true, graduate, otherwise undergrad.
The double is multiplied by 4 to get the GPA.
Random r = new Random();
List<Student> students = new ArrayList<>();
for (int i = 0; i < 10; i++) {
students.add(r.nextBoolean() ?
new Graduate(i+1, r.nextDouble() * 4) :
new Undergraduate(i+1, r.nextDouble() * 4));
}
Note, If you change the displayStudent() method to toString() like so
#Override
public String toString() {
return getLevel() + " ID>> " + getID() + ", GPA>> "
+ getGPA() + ", Status>> " + getStatus();
}
You can just print the object directly without having to call any method.
You will probably need to format the GPA to eliminate unnecessary precision. Check out String.format.

How do I create an boolean equals method compares objects in an array

My programming assignment tasked me with writing an increase/decreasePay abstract method that must be put in my abstract employee class. I can't seem to get the the method correct in HourlyWorker so that it will take increase or decrease the pay by a "percentage". My math is sound (monthly pay - or + (monthly pay * the percentage), but my output in my test class is coming out the same after increasing/decreasing pay. Any help?
Employee class:
abstract public class Employee
{
private String lastName;
private String firstName;
private String ID;
public abstract void increasePay(double percentage);
public abstract void decreasePay(double percentage);
public abstract double getMonthlyPay();
public Employee(String last, String first, String ID)
{
lastName = last;
firstName = first;
this.ID = ID;
}
public void setLast(String last)
{
lastName = last;
}
public void setFirst(String first)
{
firstName = first;
}
public void setIdNumber(String ID)
{
this.ID = ID;
}
public String getLastName()
{
return lastName;
}
public String getFirstName()
{
return firstName;
}
public String getName()
{
return firstName + lastName;
}
public String getIdNumber()
{
return ID;
}
}
HourlyWorkerClass
public class HourlyWorker extends Employee
{
private int hours;
private double hourlyRate;
private double monthlyPay;
public HourlyWorker(String last, String first, String ID, double rate)
{
super(last, first, ID);
hourlyRate = rate;
}
public void setHours(int hours)
{
this.hours = hours;
}
public int getHours()
{
return hours;
}
public void setHourlyRate(double rate)
{
if ( hours > 160 )
this.hourlyRate = hourlyRate * 1.5;
else
this.hourlyRate = rate;
}
public double getHourlyRate()
{
return hourlyRate;
}
public void setMonthlyPay(double monthlyPay)
{
monthlyPay = hourlyRate * hours;
}
public double getMonthlyPay()
{
return hourlyRate * hours;
}
public void increasePay(double percentage)
{
monthlyPay = monthlyPay* percentage;
}
public void decreasePay(double percentage)
{
monthlyPay = monthlyPay* percentage;
}
public String toString()
{
String result = "Name: " + getFirstName() + " " + getLastName() + "\nID: "
+ getIdNumber() + " \nHourly Rate: " + hourlyRate;
return result;
}
}
Testing class (currently testing increase
public class TestEmployee2
{
public static void main(String[] args)
{
Employee [] staff = new Employee[3];
Supervisor sup = new Supervisor("Boss", "Jim", "JB7865", 54000);
HourlyWorker hw1 = new HourlyWorker("Bee", "Busy", "BB1265", 11.95);
hw1.setHours(200);
staff[0] = sup;
staff[1] = hw1;
System.out.println(staff[0].getMonthlyPay());
staff[0].increasePay(5);
System.out.println(staff[0].getMonthlyPay());
System.out.println(staff[1].getMonthlyPay());
staff[1].increasePay(10);
System.out.println(staff[1].getMonthlyPay());
}
}
Supervisor class:
public class Supervisor extends Employee
{
private double annualSalary;
private double monthlyPay;
public Supervisor(String last, String first, String ID, double salary)
{
super(last, first, ID);
annualSalary = salary;
}
public void setAnnualSalary(double salary)
{
annualSalary = salary;
}
public double getAnnualSalary()
{
return annualSalary;
}
public double getMonthlyPay()
{
return ((annualSalary + (annualSalary * .02)) / 12);
}
public void increasePay(double percentage)
{
monthlyPay = monthlyPay* percentage;
}
public void decreasePay(double percentage)
{
monthlyPay = monthlyPay* percentage;
}
public String toString()
{
String result = "Name: " + getFirstName() + " " + getLastName() + "\nID: "
+ getIdNumber() + "\nAnnual Salary: " + annualSalary;
return result;
}
}
Output is:
4590.0 4590.0 2390.0 2390.0
Doesn't appear to be modifying getMonthlyPay()
Should be:
4590.00 4819.50 2390.00 2629.00
Generally, when implementing equals(), you compare “key” fields whose values don’t change for the entity, and don’t compare “state” fields whose values change from time to time.
You are comparing sharePrice, when I believe you should be comparing symbol.
When you do list.indexOf(temp), what that does, right now, is look for a Stock that is equals to the argument passed to it -- so it looks for a Stock with price zero, not caring about the symbol at all. That's what the code does right now.
Honestly, using indexOf and equals is not really appropriate for this problem. indexOf is really only useful when you have something that's totally equal to the target you're looking for.
The best way to do something like this is
Optional<Stock> foundStock = list.stream().filter(stock -> stock.getName().equals(symbol)).findAny();
if (foundStock.isPresent()) {
// do something with foundStock.get()
} else {
// no found stock
}
indexOf() is a method return the index of the first occurrence of the specified element in the returned list. If the list does not contain this element, value -1 is returned.
More formally, return the lowest index i that meets the following conditions:
if(o==null? get(i)==null :o.equals(get(i))){
return i;
}
return -1;
If there is no such index, return -1.
And you have override the equals method, I guess you just want to focus on the same price Stock?:
#Override
public boolean equals(Object obj){
if (obj instanceof Stock){
Stock other = (Stock) obj;
return getPrice() == other.getPrice();
}
return false;
}
As my opinion, you have use List<Stock> list so the Object in the list is all Stock. Maybe it could be simplifed:
#Override
public boolean equals(Object obj){
Stock other = (Stock) obj;
return getPrice() == other.getPrice();
}

Regex to read the following formatted string pattern

I want to read and map the following formatted lines into java bean
80 : (1,53.38,€45) (2,88.62,€98) (3,78.48,€3) (4,72.30,€76) (5,30.18,€9)
7 : (1,10.02,€5) (2,8.2,€9) (3,7.8,€2) (4,7.0,€6) (5,3.18,€9)
So here the digit before : will be captured as a int value and will be mapped on totalWeight and repetive patterns like (1,53.38,€45) will be mapped to items
Here is my java bean
public class Package {
private double maxWeigh; \\ so the digit value before : will be here
private List<Product> products; \\ (1,53.38,€45) will be parsed to product class
public double getMaxWeigh() {
return maxWeigh;
}
public void setMaxWeigh(double maxWeigh) {
this.maxWeigh = maxWeigh;
}
public List<Product> getProducts() {
return products;
}
public void setProducts(List<Product> products) {
this.products = products;
}
}
Here is my product class
public class Product {
private int index;
private double weight;
private double cost;
private String currencySymbol;
public double getWeight() {
return weight;
}
public void setWeight(double weight) {
this.weight = weight;
}
public double getCost() {
return cost;
}
public void setCost(double cost) {
this.cost = cost;
}
public String getCurrencySymbol() {
return currencySymbol;
}
public void setCurrencySymbol(String currencySymbol) {
this.currencySymbol = currencySymbol;
}
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
}
This is what i tried so far but this is for only products part i want to capture whole line at once
\\((\\d+),(\\d+\\.?\\d*?),€?(\\d+)\\)
Here is a code that lets you iterate over each token (a,b,c) and retrieve their members.
It uses named capturing groups.
import java.util.regex.*;
public static void main(String[] args) {
Pattern headPattern = Pattern.compile("^(\\d+).*");
Pattern tailPattern = Pattern.compile("\\((?<p1>\\d),(?<p2>\\d+\\.\\d+),(?<p3>€\\d+)\\)");
Matcher m1 = headPattern.matcher("80 : (1,53.38,€45) (2,88.62,€98) (3,78.48,€3) (4,72.30,€76) (5,30.18,€9)");
Matcher m2 = tailPattern.matcher("80 : (1,53.38,€45) (2,88.62,€98) (3,78.48,€3) (4,72.30,€76) (5,30.18,€9)");
m1.matches();
System.out.println("p0 = " + m1.group(1));
while(m2.find()) {
System.out.println("token = " + m2.group());
System.out.println("p1 = " + m2.group("p1"));
System.out.println("p2 = " + m2.group("p2"));
System.out.println("p3 = " + m2.group("p3"));
}
}

How can I access a child method in an ArrayList of parent type?

I am working on a problem wherein I need to create a virtual Dessert Shoppe with Java classes. I need to print a sort of receipt that is formatted in a certain way, and I have a class Sundae. I also have an ArrayList of type DessertItem (superclass to Ice Cream, which is superclass to Sundae). I want to access a method in Sundae from this ArrayList, but it won't let me as the ArrayList type is of DessertItem.
Here is the DessertItem class:
public abstract class DessertItem {
protected String name;
public DessertItem() {
this("");
}
public DessertItem(String name) {
if (name.length() <= DessertShoppe.MAX_ITEM_NAME_SIZE)
this.name = name;
else
this.name = name.substring(0,DessertShoppe.MAX_ITEM_NAME_SIZE);
}
public final String getName() {
return name;
}
public abstract int getCost();
}
The Checkout class (which has the receipt):
import java.util.ArrayList;
public class Checkout {
ArrayList<DessertItem> dessertItems = new ArrayList<DessertItem>();
public int cost;
public void clear() {
dessertItems.clear();
}
public void enterItem(DessertItem item) {
dessertItems.add(item);
}
public int numberOfItems() {
return dessertItems.size();
}
#Override
public String toString() {
String reciept = " " + DessertShoppe.STORE_NAME + "\n" +
" --------------------\n" +
" \n";
cost = 0;
for (int i = 0; i < dessertItems.size(); i++) {
if (dessertItems.get(i) instanceof IceCream) {
reciept = reciept + " " + dessertItems.get(i).getName() + " " + Integer.toString(dessertItems.get(i).getCost()) + "\n";
} else if (dessertItems.get(i) instanceof Sundae) {
reciept = reciept + (" Unfinished\n");
// string.concat(" " + dessertItems.get(i).getName()).concat(" " + Integer.toString(dessertItems.get(i).getCost())).concat("\n");
} else if (dessertItems.get(i) instanceof Candy) {
// string.concat(" " + dessertItems.get(i).getName()).concat(" " + Integer.toString(dessertItems.get(i).getCost())).concat("\n");
} else if (dessertItems.get(i) instanceof Cookie) {
reciept = reciept + (" Unfinished\n");
// string.concat(" " + dessertItems.get(i).getName()).concat(" " + Integer.toString(dessertItems.get(i).getCost())).concat("\n");
}
cost += dessertItems.get(i).getCost();
}
double taxRate = DessertShoppe.TAX_RATE;
double tax = taxRate / 100;
reciept.concat(" \n");
reciept.concat(" Tax " + tax + "\n");
reciept.concat(" Total Cost " + (cost * (1 + tax)) + "\n");
return reciept;
}
public int totalCost() {
cost = 0;
for (int i = 0; i < dessertItems.size(); i++) {
cost += dessertItems.get(i).getCost();
}
return cost;
}
public int totalTax() {
cost = 0;
for (int i = 0; i < dessertItems.size(); i++) {
cost += dessertItems.get(i).getCost();
}
double taxRate = DessertShoppe.TAX_RATE;
double tax = taxRate / 100;
return (int) Math.round(cost * tax);
}
}
The Sundae class:
public class Sundae extends IceCream {
public String toppingName;
public int cost;
public int toppingCost;
public Sundae() {
this("", 0, "", 0);
}
public Sundae(String newName, int newCost, String newToppingName, int newToppingCost) {
if (newName.length() <= DessertShoppe.MAX_ITEM_NAME_SIZE)
this.name = newName;
else
this.name = newName.substring(0,DessertShoppe.MAX_ITEM_NAME_SIZE);
if (newToppingName.length() <= DessertShoppe.MAX_ITEM_NAME_SIZE)
this.toppingName = newToppingName;
else
this.toppingName = newToppingName.substring(0,DessertShoppe.MAX_ITEM_NAME_SIZE);
this.cost = newCost;
this.toppingCost = newToppingCost;
}
#Override
public int getCost() {
return cost + toppingCost;
}
public String getToppingName() {
return toppingName;
}
}
Have you tried casting to Sundae?
((Sundae)(dessertItems.get(i))).getName()
Something along these lines. This should work althought I have only tried it in the opposite direction: Casting a child to a parent.
You can read more about this at the polymorphism documentation by Oracle themselves.
Good luck with you project!

Polymorphism java loop error

I'm having a problem regarding a polymorphic invocation inside a loop.
I have an abstract class called Item that has two subclasses ClothingItem and SportItem and an abstract method called printBudgetGST(Items[] item) to return a string of an item with updated pricing which include tax.
Item Class :
public abstract class Item
{
private int code;
private double price;
private boolean isOnGST;
public Item()
{
}
public Item(int code,double price,boolean isOnGST)
{
this.code = code;
this.price = price;
this.isOnGST = isOnGST;
}
public void setGST(boolean isgst)
{
this.isOnGST = isgst;
}
public int getCode()
{
return code;
}
public boolean getIsOnGST()
{
return isOnGST;
}
public double getCurrentPrice()
{
return price;
}
public String toString() {
return "Item [code=" + code + ", price=" + price + ", isOnGST=" + isOnGST + "]";
}
public abstract String printBudgetGST(Item[] items);
}
ClothingItem class
public class ClothingItem extends Item
{
public ClothingItem(){
}
public ClothingItem(int code,double price,boolean isOnGST)
{
super(code,price,isOnGST);
}
#Override
public String printBudgetGST(Item[] item)
{
String stringitem ="";
for(int i=0;i<item.length;i++)
{
if(item[i].getIsOnGST()==true&&item[i].getCurrentPrice()<100.00)
{
double finalprice =(0.06*item[i].getCurrentPrice())+item[i].getCurrentPrice();
stringitem = stringitem + " " + "ClothingItem : " + item[i].getCode()+":"+"RM"+finalprice;
}
}
return stringitem;
}
}
SportsItem class:
public class SportsItem extends Item
{
public SportsItem(){
}
public SportsItem(int code,double price,boolean isOnGST)
{
super(code,price,isOnGST);
}
public String printBudgetGST(Item[] item)
{
String stringitem = "";
for(int i=0;i<item.length;i++)
{
if(item[i].getIsOnGST()==true &&item[i].getCurrentPrice()<150.00)
{
double finalprice =(0.06*item[i].getCurrentPrice())+item[i].getCurrentPrice();
stringitem = stringitem + "SportsItem : " + item[i].getCode()+":"+"RM"+finalprice;
}
}
return stringitem;
}
}
Test class :
public class Retail_Item
{
private Item[] itemList;
public Retail_Item()
{
itemList = new Item[10];
itemList[0] = new ClothingItem(10001,85,true);
itemList[1] = new ClothingItem(10002,150,false);
itemList[2] = new ClothingItem(10003,168,true);
itemList[3] = new ClothingItem(10004,43,true);
itemList[4] = new ClothingItem(10005,162,false);
itemList[5] = new SportsItem(10006,178,false);
itemList[6] = new SportsItem(10007,80,true);
itemList[7] = new SportsItem(10008,191,false);
itemList[8] = new SportsItem(10009,45,true);
itemList[9] = new SportsItem(10010,121,true);
}
public void printItem()
{
for(int i =0 ;i<itemList.length;i++)
{
if(itemList[i].getIsOnGST()==true && itemList[i].printBudgetGST(itemList).length()>0)
{
System.out.println(itemList[i].printBudgetGST(itemList));
}
}
}
}
public class TestRetailItem {
public static void main(String[] args)
{
Retail_Item ret = new Retail_Item();
ret.printItem();
}
}
OUTPUT :
The output should return a list of items which is on tax(GST) and with the updated pricing information like the example below
The problem is that you are passing to printBudgetGST the whole array of items and iterating over that array inside your implementations of printBudgetGST. Instead, you should remove that parameter and inside printBudgetGST you should simply call getCurrentPrice() and getCode() on this rather than on each item[i].
In addition, you are doing the check for maximum price (< 100 or < 150) inside the item subclasses but it's best to do this alongside the other checks in printItem. Because the max price depends on the subclass (SportsItem vs ClothinItem) I recommend you to create an abstract method boolean isOnBudget() in Item and implement accordingly in those two subclasses.
A fully fixed version of your code is
public abstract class Item {
private int code;
private double price;
private boolean isOnGST;
public Item()
{
}
public Item(int code,double price,boolean isOnGST)
{
this.code = code;
this.price = price;
this.isOnGST = isOnGST;
}
public void setGST(boolean isgst)
{
this.isOnGST = isgst;
}
public int getCode()
{
return code;
}
public boolean getIsOnGST()
{
return isOnGST;
}
public double getCurrentPrice()
{
return price;
}
public String toString() {
return "Item [code=" + code + ", price=" + price + ", isOnGST=" + isOnGST + "]";
}
public abstract String printBudgetGST();
public abstract boolean isOnBudget();
}
class ClothingItem extends Item {
public ClothingItem() {
}
public ClothingItem(int code, double price, boolean isOnGST) {
super(code, price, isOnGST);
}
#Override
public String printBudgetGST() {
String stringitem = "";
double finalprice = (0.06 * getCurrentPrice()) + getCurrentPrice();
stringitem = stringitem + " " + "ClothingItem : " + getCode() + ":" + "RM" + finalprice;
return stringitem;
}
#Override
public boolean isOnBudget() {
return getCurrentPrice() < 100.00;
}
}
class SportsItem extends Item {
public SportsItem() {
}
public SportsItem(int code, double price, boolean isOnGST) {
super(code, price, isOnGST);
}
public String printBudgetGST() {
String stringitem = "";
double finalprice = (0.06 * getCurrentPrice()) + getCurrentPrice();
stringitem = stringitem + "SportsItem : " + getCode() + ":" + "RM" + finalprice;
return stringitem;
}
#Override
public boolean isOnBudget() {
return getCurrentPrice() < 150.00;
}
}
class Retail_Item
{
private Item[] itemList;
public Retail_Item()
{
itemList = new Item[10];
itemList[0] = new ClothingItem(10001,85,true);
itemList[1] = new ClothingItem(10002,150,false);
itemList[2] = new ClothingItem(10003,168,true);
itemList[3] = new ClothingItem(10004,43,true);
itemList[4] = new ClothingItem(10005,162,false);
itemList[5] = new SportsItem(10006,178,false);
itemList[6] = new SportsItem(10007,80,true);
itemList[7] = new SportsItem(10008,191,false);
itemList[8] = new SportsItem(10009,45,true);
itemList[9] = new SportsItem(10010,121,true);
}
public void printItem() {
for(int i =0 ;i<itemList.length;i++) {
if(itemList[i].getIsOnGST()==true && itemList[i].printBudgetGST().length()>0 && itemList[i].isOnBudget())
{
System.out.println(itemList[i].printBudgetGST());
}
}
}
}
class TestRetailItem {
public static void main(String[] args) {
Retail_Item ret = new Retail_Item();
ret.printItem();
}
}

Categories

Resources