Java - subclass and superclass relationship - java

I'm working on a homework assignment for my Java course and I'm completely lost. I guess I don't fully understand subclass and superclass relationships, but I'm trying my best to trudge along. The assignment asks us to do this:
The class Stock.java represents purchased shares of a given stock. You want to create a type of object for stocks which pay dividends.
The amount of dividends that each shareholder receives is proportional to the number of shares that person owns. Not every stock pays dividends, so you wouldn't want to add this functionality directly to the Stock class. Instead, you should create a new class called DividendStock that extends Stock and adds this new behavior.
Each DividendStock object will inherit the symbol, total shares, and total cost from the Stock superclass. You will need to add a field to record the amount of the dividends paid.
The dividend payments that are recorded should be considered to be profit for the stockholder. The overall profit of a DividendStock is equal to the profit from the stock's price plus any dividends. This amount is computed as the market value (number of shares times current price) minus the total cost paid for the shares, plus the amount of dividends paid.
Here is the stock.java file
/**
* A Stock object represents purchases of shares of a
* company's stock.
*
*/
public class Stock {
private String symbol;
private int totalShares;
private double totalCost;
/**
* Initializes a new Stock with no shares purchased
* #param symbol = the symbol for the trading shares
*/
public Stock(String symbol) {
this.symbol = symbol;
totalShares = 0;
totalCost = 0.0;
}
/**
* Returns the total profit or loss earned on this stock
* #param currentPrice = the price of the share on the stock exchange
* #return
*/
public double getProfit(double currentPrice) {
double marketValue = totalShares * currentPrice;
return marketValue - totalCost;
}
/**
* Record purchase of the given shares at the given price
* #param shares = the number of shares purchased
* #param pricePerShare = the price paid for each share of stock
*/
public void purchase(int shares, double pricePerShare) {
totalShares += shares;
totalCost += shares * pricePerShare;
}
public String getSymbol() {
return symbol;
}
public void setSymbol(String symbol) {
this.symbol = symbol;
}
public int getTotalShares() {
return totalShares;
}
public void setTotalShares(int totalShares) {
this.totalShares = totalShares;
}
public double getTotalCost() {
return totalCost;
}
public void setTotalCost(double totalCost) {
this.totalCost = totalCost;
}
}
I have started working on a subclass called DividendStock.java, but I'm not sure what I'm missing and what I need to do to actually test if its working or not. Does anyone have any tips?
public class DividendStock extends Stock{
private double dividends;
private double profit;
public DividendStock(String symbol){
super(symbol);
dividends = 0.0;
profit = 0.0;
}
public double payDividend(double amountPerShare){
dividends += amountPerShare*getTotalShares();
return dividends;
}
public double profit(double amountPerShare) {
profit = super.getProfit(profit) + payDividend(amountPerShare);
return profit;
}
}

One tip, keep it simple if you don't understand it, that way you learn it best. Here a working example for you.
class MySuperClass {
protected String whoami;
MySuperClass() {
this.whoami = "I'm the Superclass";
}
void whoAmI() {
System.out.println(whoami);
}
}
class MySubClass extends MySuperClass {
MySubClass() {
super.whoami = "I'm the Subclass";
}
}
public class TestWorld {
public static void main(String[] args) {
MySuperClass bigbro = new MySuperClass();
MySubClass littlesis = new MySubClass();
bigbro.whoAmI();
littlesis.whoAmI();
}
}

Related

How do I multiply by a method in a different class java

I want to know how to call an income method that is located in a different method. Currently, my income method is located in a TaxPayer class. I want to call on this method however, and use it in the equation below income * corporate rate = tax. How do I do this?
Tax calculator:
`public class TaxCalculator {
double tax;
/**
* Creates a TaxCalculator using 2021-2022 tax rates;
*/
public TaxCalculator() {
}
/**
* Calculates a tax payer's tax assuming they are a corporation.
*
* #precondition payer != null AND payer.isCorporation()==true
* #postcondition none
*
* #param payer the tax payer
*/
public double corporaterate = 0.21;
public double taxcalc(TaxPayer income) {
tax = income.getIncome() * corporaterate;
return tax;
}
public double calculateCorporateIncomeTax(TaxPayer payer) {
if (tax < 0) {
tax = 0;
}
return tax;
}`
I am trying to call upon my method located in a different class called Tax Payer:
public class TaxPayer {
private String name;
private int age;
private boolean isCorporation;
private double income;
/**
* Creates a new taxpayer.
*
* #precondition name != null AND !name.isEmpty() AND age >= 0
* #postcondition getName()==name AND getAge()==age AND getIsBusiness()=isBusiness
*
* #param name the person or business' name
* #param age the person's age (ignored if it is a business)
* #param income the annual income
* #param isCorporation true if the taxpayer is a business, false otherwise
*/
public TaxPayer(String name, int age, double income, boolean isCorporation) {
super();
this.name = name;
this.age = age;
this.isCorporation = isCorporation;
this.income = income;
}
/**
* Gets the name
* #return the name
*/
public String getName() {
return this.name;
}
/**
* Gets the age
* #return the age
*/
public int getAge() {
return this.age;
}
/**
* Gets the taxpayer's annual income.
* #return the taxpayer's annual income.
*/
public double getIncome() {
return this.income;
}
/**
* Gets whether or not this is a corporation (and not a person)
* #return true if a corporation, false otherwise
*/
public boolean isCorporation() {
return this.isCorporation;
}
}
I want to know how to call this getIncome method.
To call method getIncome() that is a method of class TaxPayer, there are two possibilities, depending upon whether the method is a static method or an instance method.
For a static method, from the other class (such as from TaxCalculator):
tax = TaxPayer.getIncome() * corporateRate; // TaxPayer is a class; getIncome() is a static method
For instance methods, you need an instance of a TaxPayer object:
tax = taxPayer.getIncome() * corporateRate; // taxPayer is an object of type TaxPayer; getIncome is an instance method
From what you posted, it appears that you're working with an instance method, and the calculate method that calls the getIncome() method gets an instance of TaxPayer as it's parameter. If this is all true, the code seems correct. Before you call calculateCorporateIncomeTax(payer), you should verify that TaxPayer object payer is initialized correctly.
As others have stated, it would be easier to answer with full code posted.

How to add an object to array which is an instance variable of a class in java

I have two classes named Bank and BankAccount. There is a createBankAccount method in Bank in class. I want to create an object of Bank and then add it in the record array which is a instance variable of Bank class.
class BankAccount{
double balance;
int id;
// Type of the account. Can be of two types: current or savings
String accountType;
// i. Write a Constructor
public BankAccount(double balance, int id, String accountType) {
this.balance = balance;
this.id = id;
this.accountType = accountType;
}
// ii. This function increses the balance by amount
public void deposit(double amount){
balance += amount;
}
// iii. This function decreases the balance by amount
public void withdraw(double amount){
balance -= amount;
}
}
class Bank{
BankAccount records[];
double savingInterestRate = 3.5;
double currentInterestRate = 0.4;
// iv. Write a constructor
public Bank(BankAccount[] records, double savingInterestRate, double currentInterestRate) {
this.records = records;
this.savingInterestRate = savingInterestRate;
this.currentInterestRate = currentInterestRate;
}
// v. Complete the function
public void createBankAccount(double initialBalance, int accountId, String accountType){
//Create a object of BankAccount class
// Add the object to records array
BankAccount ac = new BankAccount(initialBalance, accountId, accountType);
}
}
How do I add the BankAccount object which is created in createBankAccount method to the records array??
Is there any specific requirement to use array for records? Can't you just use a list for the same and then you can add to and remove from the list as you wish.

Is my constructor efficient?

For a programming assignment, I am asked to write
"a) A generic constructor that takes no values. This constructor lets you use the account with all the fields set to their default values.
b) A constructor that takes five inputs. The first is a double and is the interest rate for the account, the second is a int as is the minimum balance for the account, the third is a double and is the overdraft fee for the account, the fourth is a double and is the ATM fee for the account, and the fifth is a double and is the bounced check fee for the account."
I am afraid that my code is redundant and inefficient. I was hoping someone would tell me what is unnecessary and/or if I am missing anything important. How can I create the generic constructor without manually initializing the fields? Also, I'm a bit worried that my second constructor does not initialize any fields besides the 5 listed as parameters.
public class BankAccount
{
/*Balance of BankAccount*/
private double balance = 0.00;
/*Minimum balance allowed for BankAccount*/
private int minimumBalance = 0;
/*Interest rate of BankAccount*/
private double interestRate = 0.00;
/*Fee given everytime withdrawal is made via ATM*/
private double ATMFee = 0.00;
/*Amount deducted from balance if there is an overdraft*/
private double overdraftFee = 0.00;
/*Number of withdrawals allowed to be made before fee*/
private int withdrawLimit = 0;
/*Value to be deducted from balance if withdrawal limit is exceeded*/
private double withdrawFee = 0.00;
/*Keeps track of how many withdrawals owner has made*/
private int withdrawCount = 0;
/*Fee for bouncing a check*/
private double bouncedCheckFee = 0.00;
/*Stores interest earned*/
private double interestEarned = 0.00;
/*Whether or not overdraft fee has been charged*/
private boolean overdraftFlag = false;
/*Generic constructor takes no parameters and initializes field values to their default values*/
public BankAccount()
{
this.balance = balance;
this.minimumBalance = minimumBalance;
this.interestRate = interestRate;
this.ATMFee = ATMFee;
this.overdraftFee = overdraftFee;
this.withdrawLimit = withdrawLimit;
this.withdrawFee = withdrawFee;
this.withdrawCount = withdrawCount;
this.bouncedCheckFee = bouncedCheckFee;
this.interestEarned = interestEarned;
this.overdraftFlag = overdraftFlag;
}
/*More specialized constructor takes 5 fields as parameters and initalizes them to their specified values*/
public BankAccount(double interestRate, int minimumBalance, double overdraftFee, double ATMFee, double bouncedCheckFee)
{
this();
this.interestRate = interestRate;
this.minimumBalance = minimumBalance;
this.overdraftFee = overdraftFee;
this.ATMFee = ATMFee;
this.bouncedCheckFee = bouncedCheckFee;
}
}
EDIT: Okay I edited my code according to everyone's advice.
Here it is. Is it good now?
public class BankAccount
{
/*Balance of BankAccount*/
private double balance = 0.00;
/*Minimum balance allowed for BankAccount*/
private int minimumBalance = 0;
/*Interest rate of BankAccount*/
private double interestRate = 0.00;
/*Fee given everytime withdrawal is made via ATM*/
private double ATMFee = 0.00;
/*Amount deducted from balance if there is an overdraft*/
private double overdraftFee = 0.00;
/*Number of withdrawals allowed to be made before fee*/
private int withdrawLimit = 0;
/*Value to be deducted from balance if withdrawal limit is exceeded*/
private double withdrawFee = 0.00;
/*Keeps track of how many withdrawals owner has made*/
private int withdrawCount = 0;
/*Fee for bouncing a check*/
private double bouncedCheckFee = 0.00;
/*Stores interest earned*/
private double interestEarned = 0.00;
/*Whether or not overdraft fee has been charged*/
private boolean overdraftFlag = false;
/*Generic constructor takes no parameters and initializes field values to their default values*/
public BankAccount()
{
}
/*More specialized constructor takes 5 fields as parameters and initalizes them to their specified values*/
public BankAccount(double interestRate, int minimumBalance, double overdraftFee, double ATMFee, double bouncedCheckFee)
{
this.interestRate = interestRate;
this.minimumBalance = minimumBalance;
this.overdraftFee = overdraftFee;
this.ATMFee = ATMFee;
this.bouncedCheckFee = bouncedCheckFee;
}
}
In your constructor with no arguments, you re-assign the values of your fields, which is superflous. If you already give them a value in the declaration, you don't need to do it again in the constructor if you don't want it to have a different value.
First off, your default BankAccount() constructor should be empty. It's just assigning the fields to themselves.
Second, please only include mandatory fields in your constructor. See my answer here and either use setters after creation or use the Builder Pattern to build out your object using optional parameters.
Hope this helps!
The default constructor repeat fields initialization that is already present in the field declarations. You can simply clean its body.
Another limit to your code is that when you have to create an object, you have to specify all the fields used in the constructor. You can avoid this, using the fluent interface and builder pattern to get code more readable.
Now i translate what i said in code.
The code for the BankAccountOptions class:
public class BankAccountOptions {
public static BankAccountOptions build() {
return new BankAccountOptions();
}
public double aTMFee;
public double balance;
public double bouncedCheckFee;
public double interestEarned;
public float interestRate;
public int minimumBalance;
public double overdraftFee;
public boolean overdraftFlag;
public int withdrawCount;
public double withdrawFee;
public int withdrawLimit;
public BankAccountOptions aTMFee(double value) {
aTMFee = value;
return this;
}
public BankAccountOptions balance(double value) {
balance = value;
return this;
}
public BankAccountOptions balance(int value) {
minimumBalance = value;
return this;
}
public BankAccountOptions bouncedCheckFee(double value) {
bouncedCheckFee = value;
return this;
}
public BankAccountOptions interestEarned(double value) {
interestEarned = value;
return this;
}
public BankAccountOptions interestRate(float value) {
interestRate = value;
return this;
}
public BankAccountOptions overdraftFee(double value) {
overdraftFee = value;
return this;
}
public BankAccountOptions overdraftFlag(boolean value) {
overdraftFlag = value;
return this;
}
public BankAccountOptions withdrawCount(int value) {
withdrawCount = value;
return this;
}
public BankAccountOptions withdrawFee(double value) {
withdrawFee = value;
return this;
}
public BankAccountOptions withdrawLimit(int value) {
withdrawLimit = value;
return this;
}
}
The class BankAccount
public class BankAccount {
/* Fee given everytime withdrawal is made via ATM */
private double ATMFee;
/* Balance of BankAccount */
private double balance;
/* Fee for bouncing a check */
private double bouncedCheckFee;
/* Stores interest earned */
private double interestEarned;
/* Interest rate of BankAccount */
private double interestRate;
/* Minimum balance allowed for BankAccount */
private int minimumBalance;
/* Amount deducted from balance if there is an overdraft */
private double overdraftFee;
/* Whether or not overdraft fee has been charged */
private boolean overdraftFlag;
/* Keeps track of how many withdrawals owner has made */
private int withdrawCount;
/* Value to be deducted from balance if withdrawal limit is exceeded */
private double withdrawFee;
/* Number of withdrawals allowed to be made before fee */
private int withdrawLimit;
/* Generic constructor takes no parameters and initializes field values to their default values */
public BankAccount() {
this(BankAccountOptions.build());
}
BankAccount(BankAccountOptions options)
}
/* More specialized constructor takes 5 fields as parameters and initalizes them to their specified values */
public BankAccount(BankAccountOptions options) {
balance = options.balance;
minimumBalance = options.minimumBalance;
interestRate = options.interestRate;
ATMFee = options.aTMFee;
overdraftFee = options.overdraftFee;
withdrawLimit = options.withdrawLimit;
withdrawFee = options.withdrawFee;
withdrawCount = options.withdrawCount;
bouncedCheckFee = options.bouncedCheckFee;
interestEarned = options.interestEarned;
overdraftFlag = options.overdraftFlag;
}
}
Now suppose you want to create a BankAccount object with default values. The code will be:
...
BankAccount account=new BankAccount();
...
If you want to create an account and modify only two attributes (i.e. minimumBalance and withdrawLimit) you can write:
...
BankAccount account=new BankAccount(BankAccountOptions.build().minimumBalance(200).withdrawLimit(4));
...

error: Private access in class

public class ProductionWorker extends Employee
{
private int shift;
private double rateOfPay;
private double hoursWorked;
ProductionWorker(String name, int id, int shift, double rateOfPay, double hoursWorked)
{
super(name, id);
this.shift = shift;
this.rateOfPay = rateOfPay;
this.hoursWorked = hoursWorked;
}
public class TeamLeader extends ProductionWorker
{
private double monthlyBonus;
TeamLeader(String name,int id, int shift, double rateOfPay, double hoursWorked, double monthlyBonus)
{
super(name, id , shift, rateOfPay, hoursWorked);
this.monthlyBonus = monthlyBonus;
}
public double calcPay()
{
double pay = 0;
//night shift
if (shift == 2)
{
pay = ((hoursWorked + hoursWorked / 2) * rateOfPay) + monthlyBonus;
}
else
{
pay = (hoursWorked * rateOfPay) + monthlyBonus;
}
return pay;
}
}
I extend the class ProductionWorker to class TeamLeader then create a method calcPay() on the class TeamLeader my problem is I need to get the value of variable shift, hoursOfWorked and rateOfPay from the class ProductionWorker so i can use the method calcPay() to my main.Can anybody help me, thank you in advance.
To gain access to the variables of parent class (ProductionWorker), you need to change the variable scope from private to protected.
Private variables are visible only within the class.
Protected variables are visible in subclasses and to all classes within the package
You may refer to this link : http://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html.
If you do not wish to set them as protected, you can create getters and setters for the variables too, but that is not the preferred way to go.
eg of getter and setter:
private int shift;
protected int getShift() {
return this.shift;
}
protected void setShift(int shift) {
this.shift = shift;
}
Because your fields are private that means that unless you create a method that returns the particular value you are looking for when the Object is instantiated, none of your other classes or their methods will be able to access that data, hence it being private.
What you need to do is create "getter" methods in your ProductionWorker class that will allow you to say something like this in your TeamLeader class:
shift = ProductionWorker.getShift();
These sorts of methods are specifically designed so that if you need to look at the fields of the Object from a different class, you can simply create the object and use its method to return the value. Here is what these methods should look like:
public int getShift()
{
return shift;
}
public double getHoursWorked()
{
return hoursWorked;
}
public double getRateOfPay()
{
return rateOfPay;
}
By putting these public methods in your superclass, you will be able to create a ProductionWorker in your TeamLeader subclass and use its methods to access the instance variables.
UPDATE
Here is some sample code that may work for your cause:
public class ProductionWorker extends Employee
{
private int shift;
private double rateOfPay;
private double hoursWorked;
ProductionWorker(String name, int id, int shift, double rateOfPay, double hoursWorked)
{
super(name, id);
this.shift = shift;
this.rateOfPay = rateOfPay;
this.hoursWorked = hoursWorked;
}
// Now we can add the "getters"
public int getShift()
{
return shift;
}
public double getHoursWorked()
{
return hoursWorked;
}
public double getRateOfPay()
{
return rateOfPay;
}
public class TeamLeader extends ProductionWorker
{
ProductionWorker prodWorker = new ProductionWorker(Jared, 10046, 2, 8.50, 12.6); // Creates a production worker you can reference
private int shift = prodWorker.getShift();
private double rateOfPay = prodWorker.getRateOfPay();
private double hoursWorked = prodWorker.getRateOfPay();
// These three statements demonstrate the getters and how they can be implemented
private double monthlyBonus;
TeamLeader(String name,int id, int shift, double rateOfPay, double hoursWorked, double monthlyBonus)
{
super(name, id , shift, rateOfPay, hoursWorked);
this.monthlyBonus = monthlyBonus;
}
public double calcPay()
{
double pay = 0;
//night shift
if (shift == 2)
{
pay = ((hoursWorked + hoursWorked / 2) * rateOfPay) + monthlyBonus;
}
else
{
pay = (hoursWorked * rateOfPay) + monthlyBonus;
}
return pay;
}
}
Keep in mind that this may not be the perfect solution for your entire project, as I cannot see the other superclass you are extending from or what your client should do with this code. This sample code is just meant to give you an idea of how getters work in classes that make Objects and demonstrate how they can be used. I would definitely keep the getters I set for you.
Also
Make sure that for every instance variable you have for an Object, you should have a getter for each one. You will find you might need to access that data from time to time to make calculations in a client.

Java methods and classes

I'm having a bit of trouble with one of my assignments given to me by my professor. Here is the prompt:
Modify the Customer class to include changeStreetO, changeCityO, changeStateO, and changeZipO methods. Modify the Account class to include a changeAddressO method that has street, city, state, and zip parameters. Modify the Bank application to test the changeAddressO method.
I have the changeStreetO, changeCityO, and changeStateO, and changeZipO. However, I'm confused on the section in bold with the ChangeAddressO method. I think I understand how to write the parameters, but I'm unsure of what is supposed to go within the actual method, and how it fits in with the rest of the program. Here is my current code.
import java.text.NumberFormat;
import java.io.*;
import java.util.*;
public class BankModification
{
public class Account
{
private double balance;
private Customer cust;
public Account(double bal, String fName, String lName, String str, String city, String st, String zip)
{
balance = bal;
cust = new Customer(fName, lName, str, city, st, zip);
/**
* Returns the current balance
* pre: none
* post: The account balance has been returned
*/
}
public double getBalance()
{
return (balance);
}
/**
* A deposit is made to the account
* pre: none
* post: The balance has been increased by the amount of the deposit.
*/
public void deposit(double amt)
{
balance += amt;
/**
* A withdrawal is made from the account if there is enough money
* pre: none
* post: The balance has been decreased by the amount withdrawn.
*/
}
public void withdrawal(double amt)
{
if (amt <= balance)
balance -= amt;
else
System. out. println ("Not enough money in account.");
}
/**
* Returns a String that represents the Account object.
* pre: none
* post: A string representing the Account object has been returned.
*/
public String toString()
{
String accountString;
NumberFormat money = NumberFormat.getCurrencyInstance();
accountString = cust.toString();
accountString += "Current balance is " + money.format (balance);
return (accountString) ;
}
public changeAddressO(String street, String city, String state, zip_)
{
}
public class Customer
{
private String firstName, lastName, street, city,state, zip_;
/**
* constructor
* pre: none
* post: A Customer object has been created.
* Customer data has been initialized with parameters
*/
public Customer(String fName, String lName, String str,
String c, String s, String z)
{
firstName = fName;
lastName = lName;
street = str;
city = c;
state = s;
zip_ = z;
}
/**
* Returns a String that represents the Customer Object
* pre: none
* post: A string representing the Account object has been returned.
*/
public String toString()
{
String custString;
custString=firstName + " " + lastName + "\n";
custString +=street + "\n";
custString += city + ", "+state+ " " + zip_ + "\n";
return(custString);
}
public void ChangeStreetO(String newStreet)
{
street = newStreet;
}
public void ChangeCityO(String newCity)
{
city = newCity;
}
public void ChangeStateO(String newState)
{
state = newState;
}
public void ChangeZipO(String newZip)
{
zip_ = newZip;
}
}
}
}
I'm not sure if I'm missing something essential, but without the changeAddressO method, the program compiles. I'm simply unable to figure out what I need to put in the changeAddressO since I made methods with the chageStreetO, changeCityO, changeStateO, and changeZipO. I'm still having a bit of difficulty with classes and methods. Could someone provide some insight/guidance to help figure out this problem? Thank you for your time.
You just need to change the address of the customer:
public void changeAddressO(String street, String city, String state, String zip)
{
cust.changeAddress(street);
cust.changeCity(city);
cust.changeState(state);
cust.changeZip(zip);
}
public void changeAddressO(String street, String city, String state, String zip_)
{
this.street = street;
this.city = city;
this. state = state;
this.zip_ = zip_;
}
And you are probably going to want to put it inside of your Customer class since you made the street, city, state, and zip private.
First of all, change this
public changeAddressO(String street, String city, String state, zip_)
{
}
to
public void changeAddressO(String street, String city, String state, String zip_)
{
}
All functions need a return type, and all parameters need a type before the name. This function's return type is void meaning it returns nothing to the calling function. Change it to String or int or something else as necessary.
At the very least, now your code will compile.
In addition, all of the nested classes are very confusing. Your professor didn't give it to you this way I hope.
Start by changing this:
public class BankModification
{
public class Account
{
//Lots of stuff
public class Customer
{
//Lots of stuff
}
}
}
to this (eliminating all publics except the first):
public class BankModification
{
}
class Account
{
//Lots of stuff
}
class Customer
{
//Lots of stuff
}
This doesn't change anything functionally, but at least it's less confusing (notice there's nothing in BankModification which isn't very helpful.)
"Modify the Bank application to test the changeAddressO method."
What bank application? I would expect to see a
public static final void main(String[] as_cmdLineParams)
somewhere in there. This is the function that actually executes when you type java BankModification on the command line (since BankModification is the public class, only its main will be executed).
Some random observations to at least get you thinking.

Categories