I'm trying to understand Inheritance a little better but I can't seem to get it to work. I'm creating a base object for a pizza. A base, deep pan or thin. I have 2 classes, Pizza, PizzaBase. I'm keeping the private variables in Pizza, and trying to call them when building my pizzabase. Here's my 2 classes. But its not working. I get the message setCost(double) is undefined for the type Pizza
You code is wrong in every way.
Listen to the compiler: if it says you can't call setCost() on Pizza because there is no such method, it means you didn't define it.
You ought to do something more like this:
public class Pizza {
private double cost; // double is NOT a good idea for money
public Pizza(double cost) {
if (cost < 0.0) throw new IllegalArgumentException("we won't pay you to take our pizza!");
this.cost = cost;
}
public double getCost() { return this.cost; }
}
public class ThinPizza extends Pizza {
private static final double DEFAULT_COST = 2.0;
public ThinPizza() { this(DEFAULT_COST); }
public ThinPizza(double cost) { super(cost); }
}
public class ThickPizza extends Pizza {
private static final double DEFAULT_COST = 5.0;
public ThickPizza() { this(DEFAULT_COST); }
public ThickPizza(double cost) { super(cost); }
}
You can call getCost() on thin and thick pizza, because it IS-A Pizza.
Related
I have two abstract classes i.e. Medicine and Prescription. All code can be found at https://codeshare.io/aVAdr3 These two classes have subclasses, the class hierarchy diagram is as follows:
and...
The medicine java file:
abstract class Medicine {
public String name;
public int price;
public Medicine (String name, int price) {
this.name = name;
this.price = price;
}
public int getPrice () {
return price;
}
public void setPrice (int newPrice){
price = newPrice;
}
}
class commonDrug extends Medicine {
public commonDrug (String name, int price) {
super(name, price);
}
}
The Prescription java file:
abstract class Prescription {
protected Medicine med;
public Prescription(Medicine med) {
this.med = med;
}
}
class bluePrescription extends Prescription {
public bluePrescription (Medicine med) {
super(med);
System.out.println(med.getPrice()+ "<-- Price for bluePrescription, it should be 30, but the calculations in pPrescriptions affect it.");
}
}
class whitePrescription extends Prescription {
public whitePrescription (Medicine med) {
super(med);
}
}
class pPrescription extends whitePrescription {
public pPrescription (Medicine med) {
super(med);
System.out.println(med.getPrice()+ "<-- Price before calculation for pPrescription");
//Calculations
int priceWithDiscount;
if (med.getPrice()<=20) {priceWithDiscount=0;}
else {priceWithDiscount= med.getPrice()-20;}
med.setPrice(priceWithDiscount);
System.out.println(med.getPrice()+ "<-- Price after calculation for pPrescription");
}
}
The test program is as follows:
class TestProgram {
public static void main (String[] args) {
//Medicine object
commonDrug drug1 = new commonDrug("Paracetamol", 30);
//Prescription objects:
pPrescription prescription1 = new pPrescription(drug1);
bluePrescription prescription2 = new bluePrescription(drug1);
}
}
And when you run the test program you get this in the terminal:
30<-- Price before calculation for pPrescription
10<-- Price after calculation for pPrescription
10<-- Price for bluePrescription, it should be 30, but the calculations in pPrescriptions affect it.
I've been trying to solve this for hours, I can't figure out how I can perform calculations in the pPrescription constructor without affecting instances of bluePrescription. Why is this happening? pPrescription is a subclass of whitePrescriptions, not bluePrescriptions. Anyhow, to instances of a class are completely separate, getPrice and setPrice are not static, so why is using them affecting all the instances of Medicine?
why is using them affecting all the instances of Medicine?
There is only once instance of Medicine in your code.
You pass the same object, i.e. drug1 to both pPrescription and bluePrescription class constructors.
As there's only one object (drug1) that is passed to both classes, if any class modifies it, changes will be reflected everywhere you refer to that object.
One way to fix the problem is to not save the discounted price and just calculate it whenever you need it using a method in the pPrescription class.
class pPrescription extends whitePrescription {
...
public int getDiscountedPrice() {
return med.getPrice() <= 20 ? 0 : med.getPrice() - 20;
}
}
Side note: Class names should begin with a capital letter.
I have a user defined package called Drinks,
which has a few classes
Drinks
Water
Cocoa (extends Water)
Coffee (extends Water)
CalculateDrinks
after compiling the package, I created a class called Cappuccino extending Coffee, in default package, which has these classes.
Default
Cappuccino
TestPackage
In CalculateDrinks, it has a method called calculatePrice() which calculates the sum of every getPrice() of Drinks, including Cappuccino class (it also has the getPrice method).
I would to ask, how does the calculatePrice() method of the CalculateDrinks class know about the methods of getPrice() in Cappuccino class?
Any help would be appreciated. Please tell me if you would like to see the source code.
Edit:
added some essential parts of code
TestPackage.java
public class TestPackage{
public void static main(String[] args){
Coffee coffee = new Coffee(150); //that is the price
Cappuccino cap = new Cappuccino("snowman");
Drinks drinks = {coffee, cap};
CalculateDrinks cal = new CalculateDrinks(drinks);
System.out.println("The total price of all drinks is " + cal.getTotalPrice()); //it should return 350
}
}
CalculateDrinks.java
public class CalculateDrinks{
private int totalPrice;
private Drinks drinks[];
CalculateDrinks(Drinks drinks[]){
this.drinks = drinks;
calculatePrice();
}
public void calculatePrice(){
for (Drinks drink in drinks){
totalPrice += drink.getPrice();
}
}
public int getTotalPrice(){
return totalPrice;
}
}
Cappuccino.java
public class Cappuccino extends Coffee{
private String pattern;
Cappuccino(String pattern){
this.pattern = pattern;
}
public int getPrice(){
return super.getPrice() + 50;
}
}
Because in calculatePrice() it is calling getPrice() method for each drink object separately.
public void calculatePrice(){
for (Drinks drink in drinks){
totalPrice += drink.getPrice();
}
}
In first step of for loop above; it calls coffe.getPrice() because first drink in drinks array is a coffe object.
In second step; it calls getPrice()of Cappuccino object cap.getPrice().
You should be aware of getPrice() method is overwritten for each child class and every object is calling its own getPrice() method.
Lodgings in Oshkosh can be classified into three kinds – Hotels (modeled by the number of rooms and star rating), Hostels (modeled by the number of rooms and whether bike rentals are available), and Bed-n-Breakfasts (modeled by the number of rooms and whether late arrivals are allowed). Rates per room per night are always fixed and cost $40, $20 and $55 for Hotels, Hostels and Bed-n-Breakfasts respectively.The skeleton code for an inheritance hierarchy that models this scenario is stubbed out below. Complete all missing parts so that the code compiles, models the inheritance hierarchy, and has all the functionality described above. You should decide which classes the appropriate data members are stored in, and the types of those data members. In every class, complete theconstructor and provide a method, computeRate,which takes as parameter the number of nights spent and returns the total room rate for that lodging.No other methods should be provided.
Can someone give me some tips on weather you think I am going about this problem in the right way. the main thing that I am having issues with is the computeRate method. Im not sure how to set the prices of the Lodgings for hotels, Bed-n-Breakfasts, and hostels. I tried using super but im not completely sure if thats what I am supposed to do.
// parent class
public class Lodging
{
int sum;
int price;
public Lodging( int price ) {
this.price = price;
}
}
public double computeRate(int numberOfNights){
price *= numberOfNights;
return sum;
}
// child class
public class Hostel extends Lodging
{
private int numberOfRooms;
private boolean bikeRentals;
public Hostel( int rooms, boolean rentals) {
super(20);
this.numberOfRooms = rooms;
this.bikeRentals = rentals;
}
}
// child class
public class Hotel extends Lodging
{
private int rooms;
private int starRating;
public Hotel( int rooms, int starRating ) {
super(40);
this.rooms = rooms;
this.starRating = starRating;
}
}
// child class
public class BednBreakfast extends Lodging
{
private int numberOfRooms;
private boolean lateArrivals;
public BednBreakfast( int rooms, boolean late ){
super(55);
this.numberOfRooms = rooms;
this.late = late;
here is the given skeleton code
class Lodging
{
public Lodging( )
{
}
}//End class Lodging
class Hotel
{
public Hotel( )
{
}
}//End class Hotel
class Hostel
{
public Hostel( )
{
}
}//End class Hostel
class BednBreakfast
{
public BednBreakfast ( )
{
}
}//End class BednBreakfast
Each of your classes has rooms, so I would move that to the parent class, and add it to the constructor.
Also, a Lodging is an abstract concept, so you cannot make a new Lodging(), you need a specific instance of one.
public abstract class Lodging {
private double nightlyRate;
private int capacity;
public Lodging( int capacity, double rate ) {
nightlyRate = rate;
this.capacity = capacity;
}
public double computeRate(int numberOfNights){
return this.nightlyRate * numberOfNights;
}
}
Then, there's nothing wrong with super(rooms, 20), for the Hostel example. It's correctly setting up the parent class's fields, and each subclass will inherit the super class's computeRate() method. The problem description doesn't indicate it needs to be overriden.
I have created two classes, when I entered negative quantity and negative price it does not set to be "0" and "0.0" respectively as I assigned condition in setitmprch(int itmprch) and setitmprch(int itmprch) methods. Kindly tell where I did a mistake.
public class INVOICE {
private String pn;
private String pdscp;
private int itmprch;
private double prpitm;
private double amount;
public INVOICE(String pn, String pdscp, int itmprch, double prpitm ){
this.pn=pn;
this.pdscp=pdscp;
this.itmprch=itmprch;
this.prpitm=prpitm;
}
public void setpn(String pn){
this.pn=pn;
}
public void setpdscp(String pdscp){
this.pdscp=pdscp;
}
public void setitmprch(int itmprch){
if (itmprch < 0)
itmprch=0;
}
public void setprpitm(double prpitm){
if(prpitm > 0.0)
this.prpitm=prpitm;
else if(prpitm < 0.0)
this.prpitm=0.0;
}
public String getpn(){
return pn;
}
public String getpdscp(){
return pdscp;
}
public int getitmprch(){
return itmprch;
}
public double getprpitm(){
return prpitm;
}
public double getInvoiceAmount(){
amount= getitmprch()*getprpitm();
return amount;
}
}
public class INVOICETEST {
public static void main(String[] args) {
// TODO code application logic here
INVOICE in= new INVOICE("Mercedez","Arw 777",-3,-2.0);
System.out.printf("Part number is: %s\n",in.getpn());
System.out.printf("Part decription is: %s\n", in.getpdscp());
System.out.printf("Item purchased: %s\n",in.getitmprch());
System.out.printf("Price per item is: %s\n",in.getprpitm());
System.out.printf("Total amount is: %s\n",in.getInvoiceAmount());
}
}
You are assigning values to the method parameters, which will be lost as soon as you exit your method. Add this.itmprch = itmprch to your setitmprch method. Also have a look at some Java programming guidelines to improve code readability.
public void setitmprch(int itmprch){
if (itmprch < 0)
itmprch=0;
this.itmprch = itmprch;
}
Also your constructor should call the setter methods instead of assign values directly. It would look something like this:
public INVOICE(String pn, String pdscp, int itmprch, double prpitm ){
setpn(pn);
setpdscp(pdscp);
setitmprch(itmprch);
setprpitm(prpitm);
}
Don't use all caps for class names.
Use more descriptive variable names - my eyes are bleeding looking at this and it takes 10x longer to understand than it should.
Use automatic properties rather than having private backing fields and void methods to set/get.
Use property for simple calculations such as working out invoice amount.
Don't asssign to private variable then return said variable.
Use unit tests to test your logic rather than a main method. What happens when your code grows, how are you going to test it all using one entry point?
Don't use protected keywords like in for variable names (in your main function).
The following code is in C#, but it should be easily transcribable to Java. Do some research on unit testing frameworks for Java and try and incorporate that into your workflow.
public class Invoice
{
public string ModelName { get; set; }
public double Price { get; set; }
public double Amount { get; set; }
public double InvoiceAmount => Price * Amount;
}
[TestClass]
public class InvoiceTest
{
[TestMethod]
public void TestInvoiceAmount()
{
// Arrange
var testInvoice = new Invoice()
{
ModelName = "Audi R8",
Price = 5000.0,
Amount = 1
};
// Act
double invoiceAmount = testInvoice.InvoiceAmount;
// Assert
Assert.IsTrue(invoiceAmount == 5000.0);
}
}
Given the Kickback class, and the three subclasses that are subclasses of Store which is a subclass of Kickback. With the understanding that the Kicker member in this class holds the Kickback points which are encapsulated to be returned to be returned to the dummy in the Person class. How do I get the kicker member in the Kickback subclass to be transferable amongst the three gas stations. So in other words, how do I set the kicker in Kickback and the encapsulated member points in Person to hold 85 points after a variation of Divine visits and 210 points after earning 125 points at a 76 visit? The following code is the Kickback class, the Person object, and the gas stations described above. Any honest help is appreciated. If it still may be a big code- dump, I apologize; I am trying to be as straightforward as I can.
Kickback
import java.util.*;
public class Kickback{
public static final int START = 0;
public static final int REWARD = 50;
protected Person visitor;
protected int purchase, kicker;
protected String name;
public Kickback(){
visitor = new Person(purchase,kicker);
name = "Darin Douglas";
}
public double get_points(){
return kicker += purchase/REWARD;
}
public boolean redeem_points(){
if(kicker < purchase){
purchase -= kicker;
zeroKB();
return true;
}
kicker -= purchase;
return false;
}
public double zeroKB(){
return kicker = START;
}
}
Divine
public class Divine extends Store{
protected int puncher, drinks;
protected String freebie;
public static final double COST = 99;
public static final int COFFEES = 5;
public static final String FREEBIE = "Congratulations, you have earned a free coffee!";
public Divine(){
super();
puncher = COFFEES;
freebie = FREEBIE;
}
public void init(){
drink();
purchase += drinks*COST;
System.out.println("Just note:\n You have " +drinks+ " and your purchase so far is "+purchase);
super.init();
System.out.println(toString());
}
public void drink(){
System.out.print("How many coffees?\n99 cents each\n");
drinks = scan.nextInt();
if(puncher == super.START)
free_coffee();
puncher -= drinks;
}
private void free_coffee(){
System.out.println(freebie);
reset();
}
public String toString(){
return name + ",\nYou have " + kicker + " points.\nAnd have " +puncher+ " coffees remaining.";
}
public int reset(){
return puncher = COFFEES;
}
}
SeventySix:
import java.util.*;
public class SeventySix extends Store{
public SeventySix(){
super();
}
public void nav(){
super.init();
System.out.print(super.toString());
}
}
Jmart:
import java.util.*;
import java.io.*;
public class Jmart extends Store{
public static final int PERCENT = 100;
public Jmart(){
super();
}
public void init(){
System.out.print("Enter in an amount: ");
purchase = scan.nextInt();
get_points();
super.spend_money();
System.out.println(super.toString());
}
public double get_points(){
return kicker += purchase/PERCENT;
}
}
The dummy:
import java.util.*;
public class Person{
private int cash, debit, amount, points;
public static final int CASH = 1000;
public static final int CREDIT = 3000;
public Person(int purchase, int kicker){
cash = CASH;
debit = CREDIT;
amount = purchase;
points = kicker;
}
public boolean use_cash(){
if(cash < amount){
amount -= cash;
System.out.println("We got " + cash + "cash.\nYour remaining balance is " + amount + "\nPlease try another method of payment.");
reset_cash();
return true;
}
cash -= amount;
return false;
}
public boolean use_card(){
if(debit < amount){
System.out.println("Card Declined.\nPlease try another method of payment.");
return true;
}
debit -= amount;
return false;
}
public double reset_cash(){
return cash = Kickback.START;
}
}
So since you've posted your entire code and the code is quite long and will take a while for just one person to decipher and debug, I will get you started. First of all, I understand that the purpose of Kickback class you've created is to model the Kickback card to store rewards points. Thus, by creating a class you've created a user-defined type. In your method "get_points" you pass "Double Kickback" as a parameter. Parameters and variables are represented by a type and an identifier which corresponds to a value. The parameter would be "Kickback myCard" or something of that sort but in this case, since you are trying to modify the value of a Kickback card, and you are within the Kickback class, you do not need a parameter of type Kickback. You just need to modify a private member of the class called cardValue that perhaps has the type double, directly. Java does not support operator overloading. You cannot just do Kickback++. So when you declare the private members, declare an attribute called myCardValue:
double myCardValue;
Thus, instead of doing
Kickback += purchase*REWARD;
you would need to modify the myCardValue member:
myCardValue += purchase*REWARD.
NOTE: Scanner SHOULD NOT be a member of Kickback and neither should those constants. Those constants should just be declared and initialized outside of the classes in your program. They're public so they will be accessible by all classes.
Given that you want to use this member in other classes, you must supply getter and setter methods (a.k.a accessor and mutator methods) that interact with the myCardValue member of Kickback class. Ex.
public static double getKickBackCardVal(){
return myCardValue;
}
Just remember, Kickback is a type/object. In your Person class, Person should have an attribute that is a declaration of an instance of the Kickback class:
Kickback myCard;
because I'm assuming in your world, you want the dummy to have a Kickback card. Hopefully this helped. I apologize for such a long and convoluted explanation but you've posted your entire code to debug and judging from your code, you've shown that you need somewhat of better a understanding of classes and objects, how they are created and interacted with.