modeling a inheritance hierarchy... java - java

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.

Related

Best way to store templated constants in Java

I have 4 motors let's say, and for each, I have some constants like the ID, the maximum speed, and the minimum power. Let's say that at some point there are going to be many constants added to this MotorConstants class, and this is what it currently looks like:
public abstract class MotorConstants{
abstract final int ID;
abstract final double MAX_SPEED, MIN_POWER;
}
// And an implementation:
public class LeftMotorConstants extends MotorConstants{
final int ID = 3;
final double MAX_SPEED = 500, MIN_POWER = 10;
}
I understand that abstract fields are not possible. What could be a good replacement for them?
I'm afraid of passing everything through the constructor/getters and setters because then after adding a field would take a lot of time and lots of lines of code, instead of the (not working) code sample.
Constants cannot be inherited and then overwritten; that defeats the purpose of calling them "constant. Methods can be overridden to return differing values (even if they return an external constant variable).
If I understand your data model, and ID belongs to a specific instance of some "part". The other fields are also specific properties to some instance, which should not belong to the overall class, so that would be done with methods.
This is where you'd use interfaces to define those common "templates" that a class needs to implement.
E.g.
interface LimitedPower {
double getMinPower();
}
interface LimitedSpeed {
double getMaxSpeed();
}
interface Identifiable {
int getId();
}
abstract class AbstractMotor implements Identifiable {
protected int id; // available to all subclasses
#Override
public int getId() {
return this.id;
}
}
class LimitedMotor extends AbstractMotor implements LimitedSpeed, LimitedPower {
private double minPower, maxSpeed;
public LimitedMotor(int id, double minPower, double maxSpeed) {
this.id = id;
this.minPower = minPower;
this.maxSpeed = maxSpeed;
}
// TODO: implement interface getter+setter functions
}
class MotorPowered {
final AbstractMotor[] motors = new AbstractMotor[4];
public MotorPowered(AbstractMotor left, AbstractMotor right, AbstractMotor top, AbstractMotor buttom) {
this.motors[0] = left;
//... etc
}
}
Then, when you actually create a specific motor, you can pass in the details for it.
final AbstractMotor left = new LimitedMotor(3, 10, 500);
MotorPowered engine = new MotorPowered(left, ...);
If you want to say "all 'limited motors' will have the same id", then you can add some final static int ID to that class, and remove the constructor parameter.
class LimitedMotor extends AbstractMotor implements LimitedSpeed, LimitedPower {
private double minPower, maxSpeed;
public static final int ID = 3;
public LimitedMotor(double minPower, double maxSpeed) {
this.id = LimitedMotor.ID;
this.minPower = minPower;
this.maxSpeed = maxSpeed;
}

Java Problem: Calculations in one subclass' constructor affecting fields of another subclass' instance

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.

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.

Temporary extending existing object in Java - is this a good idea?

I'm implementing an algorithm during which we must temporary order existing objects (we will compare them according to this order during execution of the algorithm). I'm thinking of the best way of doing that, while being consistent with OOP paradigm.
So let's think about the following example. We have objects of class Car, and now we want to use the algorithm on such objects. So I thought of making a subclass OrderedCar, which will have a unique int in its fields. This class would have a function - ArrayList<OrderedCar> defineOrder(ArrayList<Car> order), which would output OrderedCar list with numbers corresponding to the indices of a given car in order table. We would then be able to compare OrderedCars using numbers with which they were initialized. We could then execute the algorithm on OrderedCars and convert them to Cars after the algorithm terminates.
During the algorithm I need all of the methods from Car class, that's why I thought of making OrderedCar a subclass. Is this a good idea though? Also, how to create a constructor in Java, which will "copy" the Car and assign a number to it (I'm thinking of something like public OrderedCar(Car c, int order), but what to do with the car c in order to "copy" it? I don't want to copy all of the fields individually, is there some kind of shortcut in Java?)
You could favor composition over inheritance and just create a class that contains a Car and its order:
public class OrderedCar{
private int order;
private Car car;
public OrderedCar(int order, Car car){
this.order = order;
this.car = car;
}
public int getOrder(){
return order;
}
public Car getCar(){
return car;
}
}
Then you can sort this class by its order, and whenever you needed to operate on its car, you would just call the getCar() function.
If it is enough for you to compute the order basing on public methods of your Car class I think the simplest solution would be to just implement a comparator.
Here is a small example. I'm using the age property to do the sorting.
public class Car {
protected int age;
protected String manufacturer;
Car(int age, String manufacturer) {
this.age = age;
this.manufacturer = manufacturer;
}
public int getAge() {
return age;
}
public String toString() {
return this.manufacturer + " age: " + this.age;
}
}
import java.util.Comparator;
public class CarComparator implements Comparator<Car> {
public int compare(Car c1, Car c2) {
// do some complicated comparison using
// Car public methods, we simple use to
// age property here
return c1.getAge() - c2.getAge();
}
}
import java.util.ArrayList;
public class CarComparingApp {
public static void main(String[] args) {
Car ferrari = new Car(1, "Ferrari");
Car maserati = new Car(4, "Maserati");
Car subaru = new Car(3, "Subaru");
ArrayList<Car> cars = new ArrayList<Car>();
cars.add(ferrari);
cars.add(maserati);
cars.add(subaru);
cars.sort(new CarComparator());
for(Car c: cars) {
System.out.println(c);
}
}
}

consumable item design in RPG game java

right now I'm trying to write a simple Java program about Japanese RPG game mechanic.
I have trouble on implementing use of consumable items, that is, Items that change a specific status, either from variable HP or MP in 'character' class. Here is a rough code for class 'Item' right now:
abstract class Items{
int stock;
public int checkCategory();
public int use();
}
class HPitems extends Items{
public int checkCategory(){
return 1; // this only means that category '1' heals HP, not MP
}
}
class Potion extends HPitems{
public int use(){
stock--;
return 50; //this means potion heals 50 HP
}
}
so I believe you get the idea by now, I was planning to make class MPitems extends Items that return category 2. and Whenever my player object consume an item, using consume(Items e), it will check the category using multiple if statements. If Category 1 is returned, I will use the value returned from use() of the corresponding Items subclass, and add the value to player HP.I don't think there's any problem now, but if there are many Items category, such as Items that gives another status effects, I figured it won't be efficient. Is there's any better way to do this?
and by the way, this is the player class if you need it:
public class Player{
int HP;
int MP;
public void consume(Items e){
if(e.checkCategory() == 1){
this.HP = this.HP+e.use();
else{
this.MP = this.MP+e.use();
}
}
} // consume
}
Instead of using e.checkCategory, use more natural approach by dispatching
class Player {
int hp;
int mp;
void use(Potion p) {
p.use(this);
}
}
interface Potion {
void use(Player p);
}
class HPPotion implements Potion {
public void use(Player p) {
p.hp += 50;
}
}
class MPPotion implements Potion {
public void use(Player p) {
p.mp += 50;
}
}

Categories

Resources