I would appreciate any help in solving the following question.
Design and implement a subclass of GenericOrder called ComputerPartyOrder that takes an arbitrary number of different classes of ComputerPart objects, Peripheral objects, Cheese objects, Fruit objects and Service objects.
here is the code for Product class and GerericOrder class.
abstract class Product {
protected float price;
// return the price of a particular product
abstract float price();
//public getType() {
//
//}
}
//------------------------------------------------------------
class ComputerPart extends Product {
public ComputerPart(float p) {
price = p;
}
public float price() { return price; }
}
class Motherboard extends ComputerPart {
protected String manufacturer;
public Motherboard(String mfg, float p) {
super(p);
manufacturer = mfg;
}
public String getManufacturer() { return manufacturer; }
}
class RAM extends ComputerPart {
protected int size;
protected String manufacturer;
public RAM(String mfg, int size, float p) {
super(p);
this.manufacturer = mfg;
this.size = size;
}
public String getManufacturer() { return manufacturer; }
}
class Drive extends ComputerPart {
protected String type;
protected int speed;
public Drive(String type, int speed, float p) {
super(p);
this.type = type;
this.speed = speed;
}
public String getType() { return type; }
public int getSpeed() { return speed; }
}
class Peripheral extends Product {
public Peripheral(float p) {
price = p;
}
public float price() { return price; }
}
class Printer extends Peripheral {
protected String model;
public Printer(String model, float p) {
super(p);
this.model = model;
}
public String getModel() { return model; }
}
class Monitor extends Peripheral {
protected String model;
public Monitor(String model, float p) {
super(p);
this.model = model;
}
public String getModel() { return model; }
}
class Service extends Product {
public Service(float p) {
price = p;
}
public float price() { return price; }
}
class AssemblyService extends Service {
String provider;
public AssemblyService(String pv, float p) {
super(p);
provider = pv;
}
public String getProvider() { return provider; }
}
class DeliveryService extends Service {
String courier;
public DeliveryService(String c, float p) {
super(p);
courier = c;
}
public String getCourier() { return courier; }
}
//-------------------------------------------------------
class Cheese extends Product {
public Cheese(float p) {
price = p;
}
public float price() { return price; }
}
class Cheddar extends Cheese {
public Cheddar(float p) {
super(p);
}
}
class Mozzarella extends Cheese {
public Mozzarella(float p) {
super(p);
}
}
class Fruit extends Product {
public Fruit(float p) {
price = p;
}
public float price() { return price; }
}
class Apple extends Fruit {
public Apple(float p) {
super(p);
}
}
class Orange extends Fruit {
public Orange(float p) {
super(p);
}
}
GenericOrder:
import java.util.ArrayList;
import java.util.List;
public abstract class GenericOrder<T> extends Product {
private static long counter = 1;
private final long id = counter++;
private List<T> Item;
public GenericOrder() {
Item = new ArrayList<T>();
}
public long getid() {
return id;
}
public void addItem(T newItem) {
Item.add(newItem);
}
public List<T> getItem() {
return Item;
}
public void setItem(List<T> Item) {
this.Item = Item;
}
}
EDIT: Code so far
public abstract class ComputerPartyOrder extends GenericOrder {
GenericOrder GOrder = new GenericOrder() {
#Override
float price() {
return 0;
}
};
public void input(Product newitem) {
GOrder.addItem(newitem);
}
public void output() {
System.out.println(GOrder.getItem());
}
}
You have the right idea, but GenericOrder does not need a type parameter T. Instead, you can set the type of Item to Product (the superclass of all the different types of products).
public abstract class GenericOrder extends Product {
private static long counter = 1;
private final long id = counter++;
private List<Product> Item;
public GenericOrder() {
Item = new ArrayList<Product>();
}
public long getid() {
return id;
}
public void addItem(Product newItem) {
Item.add(newItem);
}
public List<Product> getItem() {
return Item;
}
public void setItem(List<Product> Item) {
this.Item = Item;
}
}
You will still be able to call addItem with any instance of a subclass of Product.
I would also suggest renaming Item to item, uppercase names are usually used for types, not variables.
Related
public interface BattleReady{
abstract int getHealth();
abstract String getName();
}
public abstract class Hero implements BattleReady{
private int health;
private int level;
private int experience;
private int maxHealth;
private double nextLevelExperience;
private Inventory inventory;
public Hero() {
health = 100;
maxHealth = 100;
level = 1;
nextLevelExperience = 100;
inventory = new Inventory();
}
public Hero(int health, int level, int experience, int maxHealth,int nextLevelExperience, Inventory inventory){
this.health = health;
this.level = level;
this.experience = experience;
this.maxHealth = maxHealth;
this.inventory = inventory;
this.nextLevelExperience = nextLevelExperience;
}
public boolean takeDamage(int amount)
{
health = health - amount;
if(health <= 0)
{
health = 0;
return false;
}
return true;
}
public int getLevel() { return level; }
public int getHealth() { return health; }
public void setHealth(int health) { this.health = health; }
public int getExperience() { return experience; }
public double getNextLevelExperience() { return nextLevelExperience; }
public void setExperience(int experience) { this.experience = experience; }
public int getMaxHealth() { return maxHealth; }
public void setMaxHealth(int maxHealth) { this.maxHealth = maxHealth; }
public Inventory getInventory() { return inventory; }
public abstract void display();
public abstract void upgradeStats();
public void incrementLevel()
{
double nextLevel = this.getNextLevelExperience();
nextLevel += getNextLevelExperience();
level += 1;
upgradeStats();
System.out.println("Hero has leveled up!");
}
public int attack(){
return (int)(Math.random()*level);
}
public abstract String getName();
}
public class Warrior extends Hero {
public Warrior() {
super();
}
public Warrior(int health, int level, int experience, int maxHealth) {
}
public void upgradeStats() {
int h = this.getHealth();
h += this.getLevel()*12;
}
public String toString() {
return "Warrior";
}
}
I need help with this erro.
I'm getting this error when compiled.
Warrior.java:1: error: Warrior is not abstract and does not override abstract method getName() in Hero
public class Warrior extends Hero
Requirement: getName() - It required to return if "Warrior is a hero" (Should this be an abstract method or not in Hero class?)
Your getting this error, because your getName() Method is abstract - you have to override it in the Warrior-Class like this:
#Override
public String getName() {
return null;
}
DonĀ“t forget to do the same thing for the display()-Method.
I would recommend annotating overriden methods with #Override for clarity. IDEs like IntelliJ can do that for you automatically.
Consider the below example, what is a good way to avoid the warning with respect to unchecked conversion below?
Usercase is as
An interface which represent a generic statemachine
Each statemachine implementation requires a service, a set of utils required while running corresponding statemachines.
A default service which provides common services across statemachines
A transaction(txn) a binder of state and service.
import java.util.function.Consumer;
public class GenericsTest {
public static void main(String[] args) {
AService service = new AService("Aservice");
new Txn<>(service).next();
new Txn<>(new DefaultState()).next();
}
}
// ----------------------------------------------------------- //
interface Service {
String getName();
<T extends Service> State<T> getState();// this is unclear how to use generics here
}
interface State<T extends Service> {
Consumer<Txn<T>> getFunction();
int getN();
}
// ----------------------------------------------------------- //
class Txn<T extends Service> {
private T service;
private State<T> current;
Txn(State<T> current) {
this.current = current;
}
Txn(T service) {
this.service = service;
this.current = this.service.getState();
}
int next() {
do {
current.getFunction().accept(this);
} while (current.getN()>0);
return current.getN();
}
public State<T> getCurrent() {
return current;
}
public void setCurrent(State<T> current) {
this.current = current;
}
}
// ----------------------------------------------------------- //
abstract class DefaultService implements Service {
private String name;
public DefaultService(String name) {
this.name = name;
}
public String getName(){
return this.name.toUpperCase();
}
}
class AService extends DefaultService implements Service {
public AService(String name) {
super(name);
}
#Override
public State<AService> getState() {
return new AState(6);
}
}
// ----------------------------------------------------------- //
class DefaultState implements State<DefaultService> {
#Override
public Consumer<Txn<DefaultService>> getFunction() {
return (txn) -> System.out.println("hurray now left is to do default at "+txn.getCurrent().getN());
}
#Override
public int getN() {
return 0;
}
}
class AState implements State<AService> {
private int n;
AState(int n) {
this.n = n;
}
#Override
public int getN() {
return n;
}
#Override
public Consumer<Txn<AService>> getFunction() {
return (txn) -> {
int n = txn.getCurrent().getN();
System.out.println(n);
txn.setCurrent(new AState(--n));
};
}
}
Basically Please program to the interfaces (4 changes listed below):
DefaultService already implements Service
State<AService> change to State<Service>
class AState implements State<Service>
program to the interfaces: class Txn<T extends Service> {
Corrected code below:
import java.util.function.Consumer;
public class GenericsTest {
AService service = new AService("Aservice");
new Txn<>(service).next();
new Txn<>(new DefaultState()).next();
}
}
// ----------------------------------------------------------- //
interface Service {
String getName();
<T extends Service> State<T> getState();// this is unclear how to use generics here
}
interface State<T extends Service> {
Consumer<Txn<T>> getFunction();
int getN();
}
// ----------------------------------------------------------- //
class Txn<T extends Service> {
private T service;
private State<T> current;
Txn(State<T> current) {
this.current = current;
}
Txn(T service) {
this.service = service;
this.current = this.service.getState();
}
int next() {
do {
current.getFunction().accept(this);
} while (current.getN()>0);
return current.getN();
}
public State<T> getCurrent() {
return current;
}
public void setCurrent(State<T> current) {
this.current = current;
}
}
// ----------------------------------------------------------- //
abstract class DefaultService implements Service {
private String name;
public DefaultService(String name) {
this.name = name;
}
public String getName(){
return this.name.toUpperCase();
}
}
class AService extends DefaultService {
public AService(String name) {
super(name);
}
#Override
public State<Service> getState() {
return new AState(6);
}
}
// ----------------------------------------------------------- //
class DefaultState implements State<DefaultService> {
#Override
public Consumer<Txn<DefaultService>> getFunction() {
return (txn) -> System.out.println("hurray now left is to do default at "+txn.getCurrent().getN());
}
#Override
public int getN() {
return 0;
}
}
class AState implements State<Service> {
private int n;
AState(int n) {
this.n = n;
}
#Override
public int getN() {
return n;
}
#Override
public Consumer<Txn<Service>> getFunction() {
return (txn) -> {
int n = txn.getCurrent().getN();
System.out.println(n);
txn.setCurrent(new AState(--n));
};
}
}
I am trying to understand and accomplish the task of trying to create a class that extends a generic class that accepts all types of classes. So far I have that working. I am trying to create a class that extends a generic holder class and have this class accept only specific objects.
Example, a class called "ComputerOrder" that will not accept an Apple or Orange object but only a ComputerPart or Peripheral object, such as Motherboard or Printer objects. Been stuck on this for 2 weeks. I can't for the life of me figure this concept out. Any help would be appreciated.
abstract class Product{
protected float price;
abstract float price();
public String toString() {
return "Price = " + String.valueOf(price) + " ";
}
}
class Apple extends Product{}
class Orange extends Product{}
class ComputerPart extends Product{
public ComputerPart(float p){
price = p;
}
public float price() {
return price;
}
}
class Motherboard extends ComputerPart{
protected String manufacturer;
public Motherboard(String mfg, float p) {
super(p);
manufacturer = mfg;
}
public String getManufacturer() {
return manufacturer;
}
}
class Peripheral extends Product{
public Peripheral(float p) {
price = p;
}
public float price() {
return price;
}
}
class Printer extends Peripheral{
protected String model;
public Printer(String model, float p) {
super(p);
this.model = model;
}
public String getModel() {
return model;
}
}
class Cheese extends Product{
public Cheese(float p) {
price = p;
}
public float price() {
return price;
}
}
class Cheddar extends Cheese{
public Cheddar(float p) {
super(p);
}
}
class GenericOrder<T>{
public ArrayList<T> storage = new ArrayList<T>();
private static int counter = 1;
public final int id;
public T obj;
public GenericOrder(){
id = counter;
counter++;
}
public void add(T item){
storage.add(item);
}
public T get(int in){
return obj;
}
public void getId(){
System.out.println(this.id);
}
public String toString(){
String ret = "";
Iterator<T> it = storage.iterator();
while (it.hasNext()) {
ret += it.next() + "\n";
}
return ret;
}
}
class ComputerOrder extends GenericOrder {
public void add(ComputerPart in){
if(in instanceof ComputerPart){
storage.add(in);
}
}
}
public class Tme2{
public static void main(String[] args){
ComputerOrder com = new ComputerOrder();
com.add(new Motherboard("bla", 3.33f))
}
}
You can do it like this:
class ComputerOrder<T extends ComputerProduct> extends GenericOrder<T> {
//...
}
Here, ComputerProduct is a class that extends Product and all your computer products like ComputerPart or Peripheral extend ComputerProduct. Similarly, you could create a class FoodProduct derived from Product, from which Apple, Orange and Cheese are derived:
class FoodOrder<T extends FoodProduct> extends GenericOrder<T> {
//...
}
The declaration <T extends ComputerProduct> is a type restriction, which ensures that all types of T are derived from ComputerPart, otherwise you will get a compiler error.
The ComputerOrder class is still generic, so you could instance an order for all computer products:
ComputerOrder order = new ComputerOrder<ComputerProduct>();
// Add peripherals, printers, motherboards...
// Apples, ... will throw compiler errors...
But you could also restrict it to peripherals only:
ComputerOrder order = new ComputerOrder<Peripheral>();
// Add peripherals, printers,...
// Apples, motherboards (ComputerProduct, but NOT Peripheral) will fail...
Hello I have got a question about TableView in JavaFX and populating the table with data from an object in the model via a getter method of this object, which is part of the model .
First of all, here is my model:
package model;
import java.util.List;
public class Carmodel {
private int carmodelID;
private Cartype cartype;
private Manufacturer manufacturer;
private DrivingLicense drivingLicense;
private String label;
private int seats;
private int kw;
private String fuelType;
private double priceDay;
private double priceKM;
private int axes;
private int loadVolume;
private int loadCapacity;
private List<Equipment> equipmentList;
public Carmodel() {
}
public int getCarmodelID() {
return carmodelID;
}
public void setCarmodelID(int carmodelID) {
this.carmodelID = carmodelID;
}
public Cartype getCartype() {
return cartype;
}
public void setCartype(Cartype cartype) {
this.cartype = cartype;
}
public Manufacturer getManufacturer() {
return manufacturer;
}
public void setManufacturer(Manufacturer manufacturer) {
this.manufacturer = manufacturer;
}
public DrivingLicense getDrivingLicense() {
return drivingLicense;
}
public void setDrivingLicense(DrivingLicense drivingLicense) {
this.drivingLicense = drivingLicense;
}
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
public int getSeats() {
return seats;
}
public void setSeats(int seats) {
this.seats = seats;
}
public int getKw() {
return kw;
}
public void setKw(int kw) {
this.kw = kw;
}
public String getFuelType() {
return fuelType;
}
public void setFuelType(String fuelType) {
this.fuelType = fuelType;
}
public double getPriceDay() {
return priceDay;
}
public void setPriceDay(double priceDay) {
this.priceDay = priceDay;
}
public double getPriceKM() {
return priceKM;
}
public void setPriceKM(double priceKM) {
this.priceKM = priceKM;
}
public int getAxes() {
return axes;
}
public void setAxes(int axes) {
this.axes = axes;
}
public int getLoadVolume() {
return loadVolume;
}
public void setLoadVolume(int loadVolume) {
this.loadVolume = loadVolume;
}
public int getLoadCapacity() {
return loadCapacity;
}
public void setLoadCapacity(int loadCapacity) {
this.loadCapacity = loadCapacity;
}
public List<Equipment> getEquipmentList() {
return equipmentList;
}
public void setEquipmentList(List<Equipment> equipmentList) {
this.equipmentList = equipmentList;
}
As you can see there is a specific member (private Manufacturer manufacturer) It is an object from the type "Manufacturer". And the Manufacturer class looks like this:
public class Manufacturer {
private int manufacturerID;
private String name;
public Manufacturer() {
}
public int getManufacturerID() {
return manufacturerID;
}
public void setManufacturerID(int manufacturerID) {
this.manufacturerID = manufacturerID;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
This is my controller for the JavaFX View:
public class CarmodelController implements Initializable {
CarmodelRepository carmodelRepository;
#FXML public TableView CarmodelTable;
#FXML public TableColumn<Carmodel,Integer> tableColumnID ;
#FXML public TableColumn<Carmodel,String> tableColumnLabel ;
#FXML public TableColumn<Carmodel, String> tableColumnManufacturer ;
#FXML public TableColumn<Carmodel,String> tableColumnCartype ;
public void initialize(URL location, ResourceBundle resources) {
carmodelRepository= new CarmodelRepository();
List<Carmodel> carmodelList= carmodelRepository.readAll();
ObservableList<Carmodel> carmodelObservableList = FXCollections.observableArrayList(carmodelList);
tableColumnID.setCellValueFactory(new PropertyValueFactory<Carmodel, Integer>("carmodelID"));
tableColumnLabel.setCellValueFactory(new PropertyValueFactory<Carmodel, String>("label"));
tableColumnManufacturer.setCellValueFactory(new PropertyValueFactory<Carmodel, String>("manufacturer")
And here is the problem:
Can I do here something like PropertyValueFactory("manufacturer.getName()"); This way it didn't work. It just populate the column of the table with memory adress
So my question is:
How can I get the name of the manufacturer, normally, in other code, you can do this by calling the method: "manufacturer.getName();" and it will give you the String with the name of the manufacturer, but how can I do this while I will populate the table with these specific carmodels?
And the end of the controller code ( filling the Table with values).
CarmodelTable.setItems(carmodelObservableList);
}
Thank you in advance!
You can do
tableColumnManufacturer.setCellValueFactory(cellData ->
new ReadOnlyStringWrapper(cellData.getValue().getManufacturer().getName());
The setCellValueFactory method expects a Callback<CellDataFeatures<Carmodel, String>, ObservableValue<String>> object. Hence cellData in this code is a CellDataFeatures<Carmodel, String> object, and cellData.getValue() gives the CarModel object for the row. Then cellData.getValue().getManufacturer().getName() gives the value you want; you just have to wrap it in a ReadOnlyObservableWrapper to get an ObservableValue<String> containing that value.
I'm making a little game with a hero having inventory filled with object.
public enum Objects_type
{
WEAPON,
ARMOR
}
public abstract class Objects_class
{
protected String name;
protected Objects_type type;
public Objects_class(String name, Objects_type type)
{
this.name = name;
this.type = type;
}
}
public abstract class Armor extends Objects_class{
int life = 0;
int res_fire = 0;
public Armor(String name, int largeur, int hauteur) {
super(name, Objects_type.ARMOR);
}
}
public abstract class Weapon extends Objects_class
{
protected int dmg_fire = 0;
public Weapon(String name) {
super(name, Objects_type.WEAPON);
}
}
public class StickOfJoy extends Weapon{
public StickOfJoy() {
super("Stick of Joy");
dmg_fire = 2;
}
}
public class ArmorOfPity extends Armor{
public ArmorOfPity()
{
super("Armor of Pity");
life = 30;
}
}
Then I have functions like :
Hero.getObject (Objects_class obj)
{
if (obj.getType == Objects_type.WEAPON)
....
}
I'd like to be able to consider the Objects_class obj as a Weapon but of course it's not possible (casting a mother to its child) so it makes me think my inheritance structure is bad.
What should I've done ?
David Conrad has some good points I recommend you read through that I won't repeat here but here is how I would do it.
Suppose you have a character that is roaming around in your game world picking up items, there can be many different items, some so different from each other in behavior they warrant the creation of a new subclass (like picking up boots vs picking up wings).
Once you pick up an item, you have the choice of letting the hero try and see what kind of item was picked up (instanceof, enums, whatever) or you can let the item figure out where it is supposed to go.
Here is a simplified example where the player has only two inventory slots, a weapon and an armor. Notice how easy it is to simply add a new item (like a health potion, or a superdupernewspecialweapon) to the mix without having to change anything in the player or do casting.
public abstract class Item {
private int ID;
private static int IDCounter;
private String name;
public Item(String name) {
this.name = name;
this.ID = IDCounter;
IDCounter++;
}
public int getID() {
return ID;
}
public String getName() {
return name;
}
public abstract void attachToPlayer(Player player);
}
public class Armor extends Item {
private int life;
private int res_fire;
public Armor(String name) {
super(name);
}
#Override
public void attachToPlayer(Player player) {
// Only equip if upgrade
if (player.getArmor().res_fire > this.res_fire)
player.setArmor(this);
}
}
public class Weapon extends Item {
private int dmg_fire;
public Weapon(String name) {
super(name);
}
// ...stuff
#Override
public void attachToPlayer(Player player) {
// Only equip this if upgrade? You decide the logic
if(player.getWeapon().dmg_fire>this.dmg_fire)
player.setWeapon(this);
}
}
public class SuperSpecialWeapon extends Weapon {
private float bonusHealthModifier = 1.0f;
public SuperSpecialWeapon(String name) {
super(name);
}
#Override
public void attachToPlayer(Player player) {
// This bonus adds +100%HP bonus to the player!
int hp = (int) ((1 + bonusHealthModifier) * player.getHealth());
player.setHealth(hp);
player.setWeapon(this);
}
}
public class Potion extends Item {
private int health = 100;
public Potion() {
super("HealthPotion");
}
#Override
public void attachToPlayer(Player player) {
// If the player has room for one more potion, pick this up
Potion[] potions = player.getHealthPotions();
for (int i = 0; i < potions.length; i++) {
if(potions[i]==null){
potions[i] = this;
break;
}
}
}
// ..other stuff
}
And finally the player
public class Player {
private Armor armor;
private Weapon weapon;
private String name;
private Potion[] healthPotions = new Potion[10];
private int health;
public Player(String name) {
this.name = name;
}
public Armor getArmor() {
return armor;
}
public Weapon getWeapon() {
return weapon;
}
public void setWeapon(Weapon weapon) {
this.weapon = weapon;
}
public void setArmor(Armor armor) {
this.armor = armor;
}
public void setHealth(int health) {
this.health = health;
}
public int getHealth() {
return health;
}
public Potion[] getHealthPotions() {
return healthPotions;
}
}
There is no need of Objects_type, since objects in Java know what type they are, and their type can be tested with the instanceof operator. You say that you cannot cast "a mother to its child", but it is possible to downcast an object to a child type. In general, it could throw a ClassCastException, but if you have tested it first with instanceof, that won't happen.
public class Objects_class {
protected String name;
public Objects_class(String name) {
this.name = name;
}
}
public class Armor extends Objects_class {
int life = 0;
int res_fire = 0;
public Armor(String name, int largeur, int hauteur) {
super(name);
}
}
public class Weapon extends Objects_class {
protected int dmg_fire = 0;
public Weapon(String name) {
super(name);
}
}
public class Hero {
public void getObject(Objects_class obj) {
if (obj instanceof Weapon) {
Weapon weapon = (Weapon) obj;
wield(weapon);
}
if (obj instanceof Armor) {
Armor armor = (Armor) obj;
wear(armor);
}
}
}
I have removed the abstract modifier from the classes since there is no need of it, but perhaps you wanted it to ensure that those base classes are never instantiated. Also, I would change the name of Objects_class to something like Item since the words Object and class have particular meanings that could cause confusion. I would also rename Hero's getObject method to something like pickUpItem since it isn't a getter, in the Java sense.