Java Parking Ticket Simulator - Class aggregation/copy constructors - java

Instructions:
• The ParkingTicket Class: This class should simulate a parking ticket. The class’s
responsibilities are as follows:
– To report the make, model, color, and license number of the illegally parked car
– To report the amount of the fine, which is $25 for the first hour or part of an
hour that the car is illegally parked, plus $10 for every additional hour or part of
an hour that the car is illegally parked
– To report the name and badge number of the police officer issuing the ticket
• The PoliceOfficer Class: This class should simulate a police officer inspecting parked
cars. The class’s responsibilities are as follows:
– To know the police officer’s name and badge number
– To examine a ParkedCar object and a ParkingMeter object, and determine whether
the car’s time has expired
– To issue a parking ticket (generate a ParkingTicket object) if the car’s time
has expired
My problem: I don't understand how I'm suppose to call both classes at the same time. In main, it's impossible. My current code actually works but I'm not sure if it's correct. I don't understand how I'm suppose to only 'report' the objects in the ParkingTicket Class without 'knowing' them. Finally I don't understand how I'm suppose to generate a ParkingTicket object in the PoliceOfficer class without creating a field for the ParkingTicket class and adding that to the constructor. Thank you to whoever helps!
//Main:
public class chapter08_PE_08 {
public static void main(String[] args) {
ParkedCar car = new ParkedCar("HONDA", "CIVIC", "SILVER", "JPO4342", 132);
ParkingMeter meter = new ParkingMeter(60);
PoliceOfficer officer = new PoliceOfficer("Millard", "0723", car, meter);
officer.issueTicket(officer);
}
}
//Police officer class:
public class PoliceOfficer {
private String officerName;
private String officerBadge;
private ParkedCar car;
private ParkingMeter meter;
public PoliceOfficer(String officerName, String officerBadge, ParkedCar car, ParkingMeter meter) {
this.officerName = officerName;
this.officerBadge = officerBadge;
this.car = new ParkedCar(car);
this.meter = new ParkingMeter(meter);
}
public PoliceOfficer(PoliceOfficer officer) {
officerName = officer.officerName;
officerBadge = officer.officerBadge;
car = officer.car;
meter = officer.meter;
}
public void setOfficerName(String officerName) {
this.officerName = officerName;
}
public void setOfficerBadge(String officerBadge) {
this.officerBadge = officerBadge;
}
public String getOfficerName() {
return officerName;
}
public String getOfficerBadge() {
return officerBadge;
}
public ParkedCar getCar() {
return new ParkedCar(car);
}
public boolean examineCars() {
return car.getMinutesParked() > meter.getTimePurchased();
}
public double calculateFine() {
double totalTime = car.getMinutesParked() / 60;
boolean fine = examineCars();
double baseFine = 25.0;
if (fine && totalTime > 1 && totalTime < 2) {
return baseFine;
} else if (fine && totalTime > 2) {
double hourlyFine = 10.0;
return baseFine + (hourlyFine * totalTime);
} else {
return 0;
}
}
public void issueTicket(PoliceOfficer officer) {
ParkingTicket ticket = new ParkingTicket(officer);
boolean fine = examineCars();
if (fine) {
System.out.println(ticket.generateTicket());;
} else {
System.out.println("Moving on...");
}
}
}
//Parking ticket class:
public class ParkingTicket {
private PoliceOfficer officer;
public ParkingTicket(PoliceOfficer officer) {
this.officer = new PoliceOfficer(officer);
}
public String generateTicket() {
return "\nParking Ticket" +
"\n--------------" +
"\nCar information: " + officer.getCar() +
"\nOfficer name: " + officer.getOfficerName() +
"\nOfficer badge number: " + officer.getOfficerBadge() +
"\nYour fine: " + String.format("$%,.2f", officer.calculateFine());
}
}

Change public void issueTicket(PoliceOfficer officer) { to take a ParkedCar as an argument rather than a PoliceOfficer.
You already have a PoliceOfficer, so no need to pass one. The officer variable on which you are calling the issueTicket already refers to a PoliceOfficer object. What you need is tell that officer what car deserves to be ticketed.
So this:
public void issueTicket( PoliceOfficer officer ) {
…becomes:
public void issueTicket( ParkedCar parkedCar ) { …
…and this:
officer.issueTicket( officer );
…becomes:
officer.issueTicket( car );

Related

Object ArrayList For-Loop Error

I have an Object ArrayList and I need to use the toString() method of the Motor object, which is a parameter of the Vehicle object. My vehicle objects are in an ArrayList which is iterated through with a for-loop (I know a foreach loop would be easier, but this is part of the assignment)
Here is the code for the loop:
for (int i = 0; i < VehicleList.size(); i++) {
System.out.println();
String info = VehicleList.get(i).toString();
Motor m = VehicleList.get(i).motor;
String motorInfo = m.toString();
System.out.println(info);
System.out.println(m);
}
There is an error that says "motor cannot be resolved or is not a field".
All of the classes should allow this to work, unless of course there is a simple mistake I am missing.
Here is the Motor class:
public class Motor {
protected String name;
protected int cylinders;
protected int bhp;
protected double displacement;
public Motor(String name, int cylinders, int bhp, double displacement) {
this.name = name;
this.cylinders = cylinders;
this.bhp = bhp;
this.displacement = displacement;
}
public String toString() {
return "Motor name= " + name + ", cylinders= " + cylinders + ", bhp=
" + bhp + ", displacement= " + displacement;
}
}
Motors and Vehicles are intitialized here (In the TestVehicle class):
//Motors
Motor EcoBoost = new Motor("EcoBoost", 6, 310, 2.3);
Motor Hemi = new Motor("Hemi", 8, 707, 5.7);
Motor P90D = new Motor("P90D", 0, 762, 0.0);
//Vehicles
Vehicle v0 = new PassCar("Ford", "Mustang", 2016, 44500.0, 5, true, EcoBoost);
Vehicle v1 = new PassCar("Tesla", "Model S", 2016, 121000.0, 2, true, P90D);
Vehicle v2= new Truck("Dodge", "Ram", 2016, 46000.0, "pickup", 1500, Hemi);
PassCar and Truck are inherited classes of Vehicle with a few more attributes. I can post the PassCar or Truck class if needed but I do not think that is where the problem is arising from. I believe it is coming from the For-Loop, specifically the line Motor m = VehicleList.get(i).motor; but I am not sure of how to fix it.
Vehicle Class:
public class Vehicle {
protected String make;
protected String model;
protected int year;
protected double price;
public Vehicle(String make, String model, int year, double price) {
this.make = make;
this.model = model;
this.year = year;
this.price = price;
}
public void description() {
System.out.println("Description");
}
public String toString() {
return "make= " + make + ", model= " + model + ", year= " + year +
", price= " + price;
}
}
EDIT: There cannot be any Getters or Setters as per the assignment requirements, and it must be an ArrayList, not a regular List. When I switch to I get the error "Type mismatch: cannot convert from ArrayList to ArrayList
Here is an image of the classes:
ArrayList<Object> VehicleList = new ArrayList<>(Arrays.asList(vehicles));
VehicleList is declared to contain instances of Object, so the compiler will only let you access methods and fields it knows exist on all instances of Object.
Change it to ArrayList<Vehicle>.
First, mind the naming convention. Variables should be named in camcelCase e.g. vehicleListinstead ofVehicleList`
I have an Object ArrayList
I believe you mean declaration of vehicleList looks like ArrayList<Object> vehicleList
Then behavior is expected because compiler only knows that VehicleList.get(i) is going to return you an Object reference. It can be a Vehicle, but it can also be anything else. So it won't allow you to access the motor field, as there is simply no such field in Object.
Change your declaration to something like List<Vehicle> vehicleList
However, as mentioned in other answer, it is not a good idea to access the field directly because of various reason. A slightly less evil way is to have getter of motor. (A better way is to provide meaningful behaviors instead of providing access to internal data)
Create an interface IMotor which is used by Vehicle class and Implemented in PassCar and other implementation of vehicle.
IMotor.java
public interface IMotor {
public Motor getMotor();
}
Motor.java
public class Motor {
protected String name;
protected int cylinders;
protected int bhp;
protected double displacement;
public Motor(String name, int cylinders, int bhp, double displacement) {
this.name = name;
this.cylinders = cylinders;
this.bhp = bhp;
this.displacement = displacement;
}
public String toString() {
return "Motor name= " + name + ", cylinders= " + cylinders + ", bhp=" + bhp + ", displacement= " + displacement;
}
}
Vehicle.java
public abstract class Vehicle implements IMotor{
protected String make;
protected String model;
protected int year;
protected double price;
public Vehicle(String make, String model, int year, double price) {
this.make = make;
this.model = model;
this.year = year;
this.price = price;
}
public String toString() {
return "make= " + make + ", model= " + model + ", year= " + year +
", price= " + price;
}
}
PassCar
public class PassCar extends Vehicle{
protected Motor motor;
public PassCar(String make, String model, int year, double price, Motor motor) {
super(make, model, year, price);
this.motor = motor;
}
public Motor getMotor() {
return motor;
}
}
Test.java
import java.util.Arrays;
import java.util.List;
public class Test {
public static void main(String[] args) {
Motor EcoBoost = new Motor("EcoBoost", 6, 310, 2.3);
Vehicle v0 = new PassCar("Ford", "Mustang", 2016, 44500.0, EcoBoost);
List<Vehicle> vehicles = Arrays.asList(v0);
System.out.println(vehicles.get(0).getMotor());
}
}
Your problem is that motor is not a member of the Vehicle class, but you are trying to access it through an expression of type Vehicle - namely vehicleList.get(i). This is forbidden, because the compiler has no way of knowing that every possible kind of Vehicle has a motor. After all, what would happen if you added a Bicycle class?
To make this work, you should remove motor from the Truck and PassCar classes, and add it to the Vehicle class. That way, vehicleList.get(i).motor would actually make sense, since the Vehicle expression would be guaranteed to refer to a Vehicle with a Motor.
It would also be recommended to use a getter for the motor field - that is, have motor as a private field of the Vehicle class, and write a method getMotor() to return it. You could then write vehicleList.get(i).getMotor() to get the Motor object associated with one Vehicle in the list.
Thanks to the help of all of your comments and my Java textbook, I managed to piece it together. Here is how I got it to work:
for (int i = 0; i < vehicleList.size(); i++) {
String motorInfo = "";
String info = "";
System.out.println();
if (vehicleList.get(i) instanceof PassCar) {
info = ((PassCar)vehicleList.get(i)).toString();
**motorInfo = ((PassCar)vehicleList.get(i)).motor.toString();**
}
else if(vehicleList.get(i) instanceof Truck) {
info = ((Truck)vehicleList.get(i)).toString();
**motorInfo = ((Truck)vehicleList.get(i)).motor.toString();**
}
Basically I had to use a polymorphic call and check if it was an instance of a PassCar or Truck.
And as for the Array and ArrayList used during the Class, I edited them like this:
Vehicle [] vehicles = new Vehicle [3];
vehicles[0] = v0;
vehicles[1] = v1;
vehicles[2] = v2;
showVehicle(vehicles);
ArrayList<Vehicle> vehicleList = new ArrayList<Vehicle>(Arrays.asList(vehicles));
System.out.println();
System.out.println("Output from ArrayList in main: ");
Thank you for the help everyone!

Implementing a Demo/Tester Program

I have a project for my java programming course.
The instructions are that we have to create a simple class and a tester class, and the class must include a Default constructor; Parameterized constructor with three parameters (make, model and price); Accessor method called getMake( ) to return the make; Accessor method called getModel( ) to return the model; Accessor method called getPrice( ) to return the price; Mutator method setMake( String newMake) to set the make; Mutator method setModel( String newModel) to set the model; and a Mutator method setPrice( double newPrice ) to set the price..
I have created my class and tester program, and my class compiles perfectly. When I try to run it, though get the error that there is no main method. Now, I followed my professor's example for the tester program and I get several errors on that. If anyone could give me the a pointer in the right direction, I would appreciate it.
My question is this: How do I implement my tester program? Do I need to create a zip file? I've tried doing so and didn't seem to help much...
The following is my code for the class:
public class Automobile
{
private String make;
private String model;
private double price;
public Automobile()
{
make = "Lexus2017";
model = "RX";
}
public Automobile(String initMake, String initModel, double initPrice)
{
make = initMake;
model = initModel;
price = initPrice;
}
public String getMake()
{
return make;
}
public String getModel()
{
return model;
}
public double getPrice()
{
return price;
}
public void setMake(String newMake)
{
make = newMake;
}
public void setModel(String newModel)
{
model = newModel;
}
Also, the following is my tester class(the one that has a lot of errors):
public class AutomobileTester
{
public static void main(String[] args)
{
Automobile make = new Automobile("Lexus 2017");
System.out.println("The car is " + make.getMake());
Automobile model = new Automobile("RX");
System.out.println("The car is " + Automobile.getModel());
Automobile price = new Automobile("43020");
System.out.println("The car is " + Automobile.getPrice());
// Use the mutator to change the make variable
Automobile.setMake("Lexus 2017");
System.out.println("The car is " + backDoor.getState());
// Use the mutator to change the model variable
Automobile.setModel("RX");
System.out.println("The car is called " + backDoor.getName());
Automobile.setPrice("43020");
System.out.println("The car is " + price.getPrice());
}
}
This is my first time working with constructors, and I'm very new to Java, so I'm sorry for any obvious errors. Thank you ahead of time for your time and help.
One of the first problems is that you do not use the proper number of parameters for your calls to the constructor, in Java (and most programming languages) you have to supply all of the required parameters to a method/function/constructor in one call. The fix for your code would be to use:
Automobile car = new Automobile("Lexus 2017", "RX", 43020.0D);
Also when you print out the cars information you first use an instance call then you use a static call, I won't go to much into the difference between the two but basically an instance call requires you to instantiate an object while a static does not. The fix for this problem would be to do:
System.out.println("The car is a " + car.getMake() + ", the brand is " + car.getModel() + ", the price is $" + car.getPrice());
As for changing the variables you should be using:
car.setMake("My New Car Make");
instead of:
Automobile.setMake("My New Car Make");
For the difference between static and instance you can look here, here, and here.
You did this correctly. You accessed the method by using the make instance variable of an Automobile class.
(side note: make is a bad name for an automobile instance, rather call it car1, or something)
Automobile make = new Automobile("Lexus 2017");
System.out.println("The car is " + make.getMake());
Now, everywhere else that you use Automobile.someMethod(), that's not right, because you need to set or get the data on one instance of the class, not the entire class.
Then, finally, you need to test the constructor with three parameters that you have in that class.
You have an error in the constructor call.
Your constructor takes three parameters (make, model and price) but when you call the method only send one. That is an error.
By default, the Java class constructor takes no parameters (in your case, this would be "new Automobile ()").
To implement the tester you have two options.
First, create the car using the constructor without parameters and then set the parameters:
Automobile auto = new Automobile();
auto.setMake("Lexus 2017");
auto.setModel("RX");
auto.setPrice(43020);
Automobile Automobile make = new Automobile ();
Another option is to use your own builder and pass parameters:
Automobile auto2 = new Automobile("Lexus 2017", "RX", 43020);
Automobile.java:
public class Automobile {
private String make;
private String model;
private double price;
public Automobile() {
}
public Automobile(String make, String model, double price) {
this.make = make;
this.model = model;
this.price = price;
}
public String getMake() {
return make;
}
public void setMake(String make) {
this.make = make;
}
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
}
AutomobileTester.java:
public class AutomobileTester {
public static void main(String[] args) {
Automobile auto = new Automobile();
auto.setMake("Lexus 2017");
auto.setModel("RX");
auto.setPrice(43020);
System.out.println("The car1 is " + auto.getMake() + " " + auto.getModel() + " " + auto.getPrice());
Automobile auto2 = new Automobile("Lexus 2017", "RX", 43020);
System.out.println("The car2 is " + auto2.getMake() + " " + auto2.getModel() + " " + auto2.getPrice());
}
}

Multiple products in a single client(arrayList)

I've been asked to program a small online sales aplication.
It sounds very simple in theory (but it's been a hell for me). I'm just supposed to have an arrayList with about 5 products and then have a client buy 1 to 5 products and print the sales total.
public class Product {
private String name;
private double price;
public Product(String name, double price) {
this.name = name;
this.price = price;
}
public String getName() {
return name;
}
public double getPrice() {
return price;
}
public String printInfo() {
return "Product: " + name + " Cost: " + price;
}
}
Then I have a client class:
public class Cliente {
private String name;
private int numPedido;
ArrayList<Producto> products = new ArrayList<Producto>();
public void listBuilder() {
Producto shirt = new Producto("Shirt", 30);
Producto tshirt = new Producto("T-Shirt", 40);
Producto sweater = new Producto("Sweater", 50);
}
public Cliente(String name, int numPedido) {
this.name = name;
this.numPedido = numPedido;
}
public Cliente() {
}
public String getName() {
return name;
}
public int getNumPedido() {
return (int) (Math.random() * 100);
}
public void addNewClient() {
name = JOptionPane.showInputDialog("Nombre: ");
}
public String printInfo() {
return "Nombre: " + name;
}
}
Right now I'm stuck thinking on how to make a client select a product and get that attached to him. I was thinking on making an arrayList of an arrayList but I'm sure that would complicate things. I know there is probably an easier way to connect them but I can't think of any. The option I have in mind is a method which shows numbers from 1 to 3(corresponding to each product) and when the user picks one it should return the price of the item.
Still not sure how to implement it in a way that the user can pick multiple products.
EDIT:
I also have an admin class that goes like this:
public class Admin {
private Client[] clientList;
public AdminPedidos() {
clientList = new Client[2];
}
public void AddContact() {
clienteList[0] = addProduct();
clienteList[1] = addProduct();
fillList();
}
public Cliente addProduct() {
String contactoString = JOptionPane.showInputDialog("Are you a new client? Press 1 if yes.");
if (contactoString.equals("1")) {
return new Cliente();
} else {
return new Cliente(); //just for testing
}
}
private void fillList() {
for (Client i : clientList) {
i.addNewClient();
}
}
public void printContact() {
for (Client i : clientList) {
System.out.println(i.printInfo());
}
}
}
You can have some purchaseProduct method attached to each Client.
public void purchaseProduct(Product product) { this.products.add(product); }
Then each Client you instantiate (Client client = new Client(name, id);) can add Products to his/her cart with the purchaseProduct method.
I'm assuming you are using some kind of user input method (Scanner). With that you can read the user's input of which Product they want and accordingly call the function with the right Product.
The listBuilder function doesn't quite make sense to me btw (and after your edit, it's really hard to make sense of what the Admin class should be/represent).
Edit: You would probably want to create an ArrayList<Product> which will be attached to each client, which you already have. I sense that you have a difficulty deciding where to put your actual Products. You should not put them inside your Client class for sure.
You should think about who/where they are going to be used. Probably in main right? So just instantiate them there first and then the Client could choose which one to purchase (via the method I introduced before):
client.purchaseProduct(product);

How do I get the kicker member to be transferrable amongst the three gas stations below?

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.

Passing to Setter and Getter methods

I have a Bread class and a Filling class which set the bread type and calories per slice as well as a filling class which sets the filling type and calories per serving... I can't seem to figure out how to pass them into the sandwich class correctly. My total calories doesn't work out
private class Sandwich {
private Bread bread;
private Filling filling;
private Bread caloriesPerSlice;
private Filling caloriesPerServing;
private Sandwich(String breadType, int caloriesPerSlice, String fillingType, int caloriesPerServing) {
setBread(bread);
setBread(caloriesPerSlice);
setFilling(caloriesPerServing);
setFilling(filling);
}
public Bread getBread() {
return bread;
}
public void setBread(Bread bread) {
this.bread = bread;
}
public Filling getFilling() {
return filling;
}
public void setFilling(Filling filling) {
this.filling = filling;
}
public int getTotalCalories(int caloriesPerSlice,int caloriesPerServing) {
(caloriesPerSlice) * 2 + caloriesPerServing = totalCalories;
return this.totalCalories;
}
}
You have your variable assignment backwards.
(caloriesPerSlice) * 2 + caloriesPerServing = totalCalories; is not valid. The variable being assigned to must be on the left.
Try:
totalCalories = (caloriesPerSlice) * 2 + caloriesPerServing;
(caloriesPerSlice) * 2 + caloriesPerServing = totalCalories; Doesn't do what you think it does.
Perhaps you mean
totalCalories = (caloriesPerSlice) * 2 + caloriesPerServing;
I see some problems in your code:
why does an instance of Sandwich should have two Bread object within? A sandwich is usually made by one type of bread.
the caloriesPerSlice and caloriesPerServing should be respectively attributes of Bread and Filling.
you can't pass a String parameter to setFilling(Filling filling) method.
(caloriesPerSlice) * 2 + caloriesPerServing is not a valid left-value and is not a valid expression because caloriesPerSlice and caloriesPerServing are objects.
This is a really basic implementation of your idea:
Bread.java
public class Bread
{
private String type;
private int caloriesPerSlice;
public Bread(String type, int caloriesPerSlice)
{
this.type = type;
this.caloriesPerSlice = caloriesPerSlice;
}
public String getType() { return type;}
public int getCaloriesPerSlice() { return caloriesPerSlice; }
public String toString()
{
return type + " (" + caloriesPerSlice + "cal)";
}
}
Filling.java
public class Filling
{
private String name;
private int caloriesPerServing;
public Filling(String name, int caloriesPerSlice)
{
this.name = name;
this.caloriesPerServing = caloriesPerSlice;
}
public String getName() { return name;}
public int getCaloriesPerServing() { return caloriesPerServing; }
public String toString()
{
return name + " (" + caloriesPerServing + "cal)";
}
}
Sandwich.java
public class Sandwich
{
private Bread bread;
private Filling filling;
public Sandwich(Bread bread, Filling filling)
{
this.bread = bread;
this.filling = filling;
}
public int getTotalCalories()
{
return 2 * bread.getCaloriesPerSlice() + filling.getCaloriesPerServing();
}
public String toString()
{
return "Bread: " + bread.toString() + "\nFilling: " + filling.toString();
}
}
Main.java
public class Main
{
public static void main(String args[])
{
Bread bread = new Bread("Baguette", 150);
System.out.println("I would like a " + bread.toString());
Filling filling = new Filling("Prosciutto di Parma", 75);
System.out.println("with " + filling.toString());
Sandwich sandwich = new Sandwich(bread, filling);
System.out.println("Your order is:");
System.out.println(sandwich.toString());
int totalCalories = sandwich.getTotalCalories();
System.out.println("The total calories are " + totalCalories);
}
}
This is the output:
I would like a Baguette (150cal)
with Prosciutto di Parma (75cal)
Your order is:
Bread: Baguette (150cal)
Filling: Prosciutto di Parma (75cal)
The total calories are 375
The class has a lot of errors:
You have a Bread caloriesPerSlice, but the constructor uses the same variable as int.
The same with the Filling caloriesPerServing and the int caloriesPerServing.
It has a private constructor. This constructor specify that the only way you can access a class of this type is through a static method in the class that returns an Sandwich object (like with the singleton pattern), which is not the case here.
The class is private: maybe I'm wrong, but a private class in java means that no one can access it.
The constructor: for example, breadType is a string object, and it's not used. You are trying to setBread with the private variable... what is that?
The constructor: caloriesPerSlice is an int type and you use it in the setBread() setter which receives a Bread type. You are mixing types.
The same with caloriesPerServing which is used in setFilling(), which receives a Filling object....
getTotalCalories: the assignment goes on the right, not the left.
I think you have a misunderstanding of OO. For example, let's see the Bread class:
If the bread class has the properties caloriesPerSlice and breadType they maybe are part of the bread type. Let's change the class to reflect those properties:
public class Bread {
private int caloriesPerSlice;
private String type;
public Bread(String type, int caloriesPerSlice)
{
this.type = type;
this.caloriesPerSlice = caloriesPerSlice;
}
public int getCaloriesPerSlice()
{
return this.caloriesPerSlice;
}
public String getType()
{
return this.type;
}
}
Here in this case the Bread is completely defined though his constructor. You can see that the class has no setter. That's because I decided it, but it's up to you if you want a parameterless constructor and setters in the class. Here in this case I only defined getters. Let's see the Filling class:
public class Filling {
private int caloriesPerServing;
private String type;
public Filling(String type, int caloriesPerServing) {
this.caloriesPerServing = caloriesPerServing;
}
public int getCaloriesPerServing()
{
return hits.caloriesPerServing;
}
public void setCaloriesPerServing(int calories)
{
this.caloriesPerServing = calories;
}
public String getType()
{
return this.type;
}
public void setType(String type)
{
this.type = type;
}
}
Here the Filling class has getters and setters. It's just for explanation purposes: in the Filling class you can set the properties through constructor or through the setters, whilst in the Bread you can only define the properties through the constructor.
Now the Sandwich maybe can receive all the properties that define a bread and a filling (like in your case), or maybe it can receive a bread and a filling). Let's see the first case:
public class Sandwich {
private Bread bread;
private Filling filling;
public Sandwich(String breadType, int caloriesPerSlice, String fillingType, int caloriesPerServing) {
this.bread = new Bread(breadType, caloriesPerSlice);
this.filling = new Filling(fillingType, caloriesPerServing);
}
public Bread getBread() {
return bread;
}
public void setBread(Bread bread) {
this.bread = bread;
}
public int getTotalCalories() {
return this.bread.getCaloriesPerSlice() * 2 + this.filling.getCaloriesPerServing();
}
}
As you can see, we received in the Sandwich constructor all the parameters which define a bread and a filling. Then, we created the Bread and Filling objects, passing their parameters. Finally, the getTotalCalories is nothing but a simple math of the bread and filling properties.
This code was just writen in a text editor. I did not checked if it's ok or not.
In this example, Sandwich becomes a class and a factory, a very important component of the class. As you can see, the construction of the Bread and Filling classes is made through the Sandwich. It has the advantage that the Sandwich controls the creation of objects, but the thing is: Is the sandwich responsible of that? Maybe not, because when you make a sandwich in your home you get the bread and the other ingredients and you just put them on the slices... the sandwich is not responsible of the creation of a bread slice... it does not make sense in the real life. Then, maybe it's a good idea to remove the object creation in the Sandwich constructor:
public Sandwich(Bread bread, Filling filling) {
this.bread = bread;
this.filling = filling
}
This case is more 'correct' because you're making a sandwich with the elements already generated in memory. It's the same when you make a sandwich in your home: you get the bread, the filling and then you make a sandwich.
I hope this can clarify a little more about OO.
Greetings!

Categories

Resources