Accessing an object of a class from another class object - java

Starting of I want to apologise for my english as I'm not a native speaker. The title might be a bit off since I was not sure how to phrase it but hopefully it will come through once I show my code.
The problem I'm phasing is I want to use the shop class to handle any purchases while storing the money variable on the player class.
Is there any way to access the money integer of the player class without creating an object of the player class in the shop class ?
I was thinking about using a static integer to store the data in but from what I've read online its bad practice to use static datatypes.
public class Beta {
public static void main(String[] args) {
Player p1 = new Player("Test");
Shop s1 = new Shop();
p1.setMoney(100);
s1.clerk(p1.getMoney());
}
}
public class Player {
private int money;
private String name;
public Player(String name) {
this.name = name;
}
public int getMoney() {
return money;
}
public void setMoney(int x) {
this.money +=x;
}
}
public class Shop {
private int money;
public void clerk(int x) {
this.money = x;
if (this.money >= total) {
question4 = false;
System.out.println("Your purchase was successful!");
if (blue > 0) {
this.addInventory("Blue", blue);
}
if (red > 0) {
this.addInventory("Red", red);
}
if (green > 0) {
this.addInventory("Green", green);
}
}
else {
question4 = false;
System.out.println("Sorry you cant afford that!");
}
}
}
}
So I cut down my code to show you only the essential parts.
What I want to do is access p1:s money variable from the player class from within the Shop class.
So far I have been passing the variable when calling it from main. Is this the only option I have or can it be accessed in any other way ?
Any help would be much appreciated!

I believe the option that follows Object-Oriented Programming principles best is to pass the actual Player in as an argument, instead of just the money.
Basically, passing just the player's money in instead of the player themselves is like just handing your wallet over to the cashier. You wouldn't do that, right?
This way, the clerk can ask the customer if they have enough money by calling player.getMoney(), and the customer can tell them the answer.
After making the purchase, the player can remove the money from their wallet themselves when the clerk asks them to via player.setMoney().
Now, you asked in a comment about "passing the actual player as an argument without creating a new object of the player class." Java passes arguments by value, and all objects' values are simply the address that hold the information for that particular instance.
So for Player p1 in Beta, let's pretend all of p1's information is stored in a block starting at...let's say, address 21343. In this case, the variable p1 only contains that single number, 21343.
Since Java passes by value, then when you call s1.clerk(Player player), the player variable will also contain 21343. Since it's editing the items contained at the same address, you've essentially passed on p1 itself instead of creating a new Player. In short, the clerk and the main method work with the same object.
The fact that Java passes by value is also why passing just the player's money in doesn't adjust it automatically: The money is an int rather than an object. Since it's an int, when you pass it to the clerk, you're just saying "Hey, clerk, this is the amount of money being worked with." But the clerk has no idea who the money belongs to, so while it can take money, or even give it some, it's essentially just setting it down on the counter, and it's the responsibility of the player to pick it up from there when they're done. By passing in the player instead, the clerk knows who the money belongs to because it's actually asking the player how much money they have.

Another potential solution would be to make p1 and s1 static variables in the Beta class. It'd look something like this:
public class Player
{
public static Player p1;
public static Shop s1;
public static void main(String[] args)
{
p1 = new Player("Test");
s1 = new Shop();
p1.setMoney(100);
s1.clerk(p1.getMoney());
}
}
From there, you'd import the Beta class in Shop, then call Beta.p1 in Shop to access p1.
Hope this helps!

Related

Use of static classes to represent different forms of currency

I coded myself an issue last night while developing a small game. The other day, I convinced myself that I should devote some of my spare time to something productive, so instead of gaming I decided I would start working on a text-based rpg. I came, then, to the issue of representing currency in game. Now, because this is just for fun, I'd like to challenge myself a bit. Instead of just representing currency as a single value ( eg: a single type of coin called "gold piece" isn't the only kind of coin in the game .)
What I decided to do was create 4 types of coin - pence, copper, denar, and oren. All 4 of the coins have values such as weight, volume, material, and name. Furthermore, the coins have exchange rates, which determine their relative values. The point of this was to permit different usages of what would otherwise be a boring old currency. My issue is that I am unsure how to implement it.
What I arrived at last night was 4 classes ( Pence, Copper, Denar, Oren, ) extending an abstract class Coin. Coin contains a lot of protected static elements, such as DENSITY, VOLUME, NAME, EXCHANGE for all 4 subclasses.
The constructors for the sub-classes look like this:
public Coppers() {
super();
super.metal = COPPER_METAL;
super.name = COPPER;
super.setVolume();
super.setDensity();
super.setWeight();
}
And the methods in the super class look like this:
protected void setDensity() {
switch( getMetal()) {
case "copper":
this.density = DENSITY_COPPER;
break;
case "silver":
this.density = DENSITY_SILVER;
break;
case "gold":
this.density = DENSITY_GOLD;
break;
default:
this.density = DENSITY_COPPER;
break;
};
}
This seems terribly... wrong. I'm not sure what the best practice would be. I asked my friends about using a static class to hold these values, and received mixed responses. The POINT of these classes though, is important. Imagine the player class has an object called Purse, which keeps track of the number of different types of coins. With their Purse, the player can exchange coins at banks, purchase goods, and sell goods for coins. It wouldn't make any sense to hold a Set of all instantiated coins, right? I just need the information, and the methods. Does implementing a static class make sense, then? How can I get all 4 coins working best, when they all share so many properties?
What you may do in this case is to use an Enum. You enumerate the constants you need, give them a type through their constructors.
Now that we have their type, we can compare it to the string you're handling within your code, if none of the types match, we set it to Density.COPPER by default.
Density density;
protected void setDensity (String metal) {
for (Density d : Density.values()) {
if (metal.equals(d.getType())) {
this.density = d;
return;
}
}
this.density = Density.COPPER;
}
enum Density {
COPPER("copper"),
SILVER("silver"),
GOLD("gold");
String type;
Density(String s) {
type = s;
}
public String getType() {
return type;
}
}
Let's work backwards here.
Imagine the player class has an object called Purse, which keeps track of the number of different types of coins. With their Purse, the player can exchange coins at banks, purchase goods, and sell goods for coins.
What this implies:
public class Purse {
private final List<Coin> coins = new ArrayList<>();
}
This tells me that enums are not sufficient (enough) here. An enum in this context describes multiple states; what you're looking for are actual objects which can hold values that you need to do some calculations on.
If our intention is to hold on to this currency, I don't see anything wrong with some central object to describe it.
In my mind, using an abstract class for this is probably fine, but you're missing a critical component: a factory to create the type of coin you want. You'll also want to reduce the responsibilities of the coin altogether - it's fine for a coin to know its value, but it shouldn't care what its value is relative to other coins; that's the responsibility of some kind of exchange object which intends to produce a number of coins based on the value of your given coin.
So let's write the constructor for the abstract class. If we're thinking of creating a generic coin, we need to know its volume, density, and weight. The name is provided by virtue of its class name, so you really shouldn't need to worry about that; you can extract it later.
If you want some sort of coin hierarchy, you can leverage Comparable; state the ordering there instead of through enumeration.
public abstract class Coin implements Comparable<Coin> {
protected final int volume;
protected final int density;
protected final int weight;
public Coin(int volume, int density, int weight) {
this.volume = volume;
this.density = density;
this.weight = weight;
}
public int getVolume() {
return volume;
}
public int getDensity() {
return density;
}
public int getWeight() {
return weight;
}
}
This describes the barebones Coin type.
For an example, let's describe the Copper type here as well. This code makes the assumption that coin of the same type is comparable otherwise it demotes itself (with Copper being at the bottom of the list).
Observe a few things:
We preserve a lot of the original logic from the parent class
We override compareTo (because we must), and we let that drive the chief way of ordering on coins.
This does not describe any sort of conversion since the coins really shouldn't need to know about that. They have no value between coins until it's time to actually convert them. Think foreign exchange.
public class Copper extends Coin {
public Copper(final int volume, final int density, final int weight) {
super(volume, density, weight);
}
#Override
public int compareTo(final Coin otherCoin) {
if(otherCoin instanceof Copper) {
return (volume - getVolume()) + (density - getDensity()) + (weight - getWeight());
}
// assume Coppers are worth the least
return Integer.MIN_VALUE;
}
}
The other currencies are left as an exercise for the reader.
The last thing I want to cover is some form of generator for all of your currencies. This is where a bit of reflection magic can really help to invoke the constructor you care about.
I've also made this return an Optional<T extends Coin> so that, in the event the generation fails for some reason, you have an optional to work with instead of null.
public class CoinFactory {
private CoinFactory() {
}
public static <T extends Coin> Optional<T> generateCoin(int weight, int volume, int density, Class<T> clazz) {
Optional<T> coin = Optional.empty();
try {
coin = Optional.of(clazz.getDeclaredConstructor(int.class, int.class, int.class)
.newInstance(weight, volume, density));
} catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
e.printStackTrace();
}
return coin;
}
}
You can use this main method to smoke test it:
public static void main(String[] args) {
final Optional<Copper> x = CoinFactory.generateCoin(10, 20, 30, Copper.class);
if(x.isPresent()) {
System.out.println(x.get());
}
}
Put a private Map in Coin for Density, with keys being "copper", "gold", and "silver", and the values being the DENSITY_ constants. setDensity() should simply run:
this.density = densityMap.get(getMetal());
Or better yet, scrap setDensity(), and instead simply have getDensity(), which returns densityMap.get(getMetal()).
Since the four kinds of coin don’t differ in behavior, one class is enough. I suggest this:
public enum Coin {
PENCE, COPPER, DENAR, OREN;
private static final String[] METAL = { "copper", "copper", "silver", "gold" };
private static final int[] VALUE = { 1, 12, 60, 360 };
public String getMetal() {
return METAL[ordinal()];
}
public int getValue() {
return VALUE[ordinal()];
}
}

Library System: Borrowing

I do not know how to do the borrowHolding() in the Library Menu I have to create.
So the purpose of the borrowHolding() is for members to be able to borrow books or videos.
This is a just a sample data of the array:
member[0] = new StandardMember("ID", "Name");
member[1] = new PremiumMember("ID", "Name");
holding[0] = new Book("ID", "Title");
holding[1] = new Video("ID", "Title", loanFee);
This is the borrowHolding() method in the TestLibrary class: (the array is in the TestLibrary class too)
public static void borrowHolding(){
String option;
option = input.next();
do{
Scanner scan = new Scanner(System.in);
int tempId = 0;
System.out.println("Enter your ID: ");
String searchID = scan.next();
for(int i = 0; i < member.length; i++){
if(member[i].getID().equals(searchID)){
tempId = i;
}
}
So for the method, I tried to write a code that will search through the array to find the memberID that wants to borrow. It is not completed yet because I believe I am not doing it correctly
There is a Member class that contains
public class Member{
public Holding[] getCurrentHoldings(){
}
}
from the name of the method, it is used to store the holdings of the members that borrowed. So if member 1 borrows a book, that book will be stored inside the array, i think. I was thinking of using an ArrayList for this method, but not sure if it would make sense.
To borrow a book or video, there are certain conditions to be able to borrow, but I do not know how to implement this into the borrowHolding(). One of the condition are in the Holding class.
public class Holding{
public boolean borrowHolding(){
if(status == true && isOnLoan() == false)
borrowDate = newDateTime(); //this is to get the time when the book or video is borrowed
return true;
}else
return false;
}
}
And there is another condition in the Member class is that the Member must have enough credit to borrow. A book loan fee will cost $10 and a video will vary from $4 or $6.
I think I wrote a few information that is not needed but I guess its better than less information.
My problem is what do I do to the borrowHolding() method in the LibraryMenu? how do I make that if a member wants to borrow a holding, the holding will go under the member's array in the member class
public class Member{
public Holding[] getCurrentHoldings(){
}
}
with the condition from the holding class if it is met, and while executing the borrowHolding method, the method from the member class will be able to subtract the member credit by the loan fee from the book or video. is it possible?
public class Member{
private int credit = 30;
public int calculateRemainingCredit(){
credit = credit - //(the loan fee from the book or video class)
}
}
If your intentions are to add a holding to the member class then this is possible. I would suggest adding an ArrayList of Holding's rather than a regular array because it seems as if the size is going to be constantly changing.
public class Member{
private ArrayList<Holding> currentholdings; // you may need to import the arraylist
private int credit;
public void init(){ // goes in constructor
currentholdings = new ArrayList<Holding>();
credit=0;
}
public void addHolding(Holding newholding){ // adds a new holding to the members array
currentholdings.add(newholding);
credit-=newholding.getFee(); // will need to add a fee variable to the holding class;
}
}
And as for checking to see whether or not the member has enough "credit", that can be done in the borrowHolding() method right after you identify the index of the array. I would just recommend adding a parameter of the member to the borrowHolding() method so you can easily access the variables from that member.
if(member[i].getID().equals(searchID)){
tempId = i;
int tempHolding; // index of whatever holding you wanted (could get this from the scanner)
if (holding[tempHolding].borrowHolding(member[tempId])){ // check status
member[tempId].addHolding(holding[tempHolding]); // they have passed the req. so you can add the holding
}
break;
}
Hope this answered your question.

How do I change the value of a variable from another class and still be able to change it within the other class?

So I'm fairly new with programming having done it for maybe just under a year at this point. I'm even more new with Java (I did C++ before). So I have variables like numberHealthPotions, health, attackDamage, and so on, in a class named Fighting. But then in my main class, there are points in the game in which the character picks up a weapon, picks up a potion, or is wounded. I just need a way to say in my main class he was wounded then change the value of the health of the character or whatever.
This is just a snipet of my code to give you an idea...
else if(inputHKitchen.equalsIgnoreCase ("examine")){
System.out.println("Examine what?");
examineWhat = in.nextLine();
if(examineWhat.equalsIgnoreCase("drawer")){
System.out.println("\tYou found a knife!");
attackDamage = 50;
System.out.println("\tYour attack damage has been increased!\n");
System.out.println(houseKitchen);
}
If your variable is static, then it might be
//note this variable must be public or protected
Player.HEALTH = 0;
if its not static, then
Player p = new Player();
p.HEALTH = 0;
I would write a series of public methods for the character that manage these various values.
For example, in the class YourCharacter:
private int attackDamage;
public void addDamage(int value)
{
attackDamage += value;
}
Then in your snippet:
if (examineWhat.equalsIgnoreCase("drawer")){
yourCharacter.addDamage(50);
}
Lots of good game-writing advice for Java can be found at java-gaming.org

Manipulating Variables using Setters and Getters

I came across this code example on another website. I've been looking at it for a while, trying to figure out something simple, but I'm having difficulty determining where to start.
How would I allow a user to enter into the console to turn the light or the fan on/off?
All this stuff with setters/getters is confusing. Writing the logic of turning something on/off seems simple, but mix it in with constructors and setters/getters and I get lost. I'm failing to understand how and where to manipulate the isOn boolean with user input.
I'd appreciate any guidance or code.
Thanks
public class Household {
public String choice;//instance variables
public boolean isOn;
//constructor
Household(String choice,boolean isOn) {
this.isOn=isOn;
this.choice=choice;
}
//methods
public String getChoice() {
return choice;
}
public void setChoice(String choice) {
this.choice = choice;
}
public boolean isOn() {
return isOn;
}
public void setOn(boolean isOn) {
this.isOn = isOn;
}
public String toString() {
return "Choice:" + getChoice() + "\tisOn:" + (isOn() ? "Yes" : "NO");
}
public static void main(String[] args) {
Household hh=new Household("toaster", true);
System.out.println(hh);
hh=new Household("fan", false);
System.out.println(hh);
}
}
You can think of a constructor as like a blueprint.
In the above picture, we have the class in the dotted box. This is the "blueprint." It's not an actual object yet, it just represents how objects should look. In the solid box is an actual object.
The constructor takes the blueprint and actually builds something from it.
Household(String choice,boolean isOn) {
this.isOn=isOn;
this.choice=choice;
}
Here, we're defining how that blueprint works. In order to build a household object, we need to supply it with a string "choice" and a boolean "isOn".
Once we have those two things, we can create a Household object.
Now, you can't turn on the lights in your house before they're built.
Once you have a Household object, you'll also have your choice and isOn fields.
Say I want to turn off whatever is in the house.
Using your code, we have a household named hh, a toaster, and an on/off switch. If you wanted to turn off the on/off switch, you'd use the setter:
public void setOn(boolean isOn) {
this.isOn = isOn;
}
The setter then sets the value of the isOn field on the hh object, as seen in the above picture.
If you wanted to know whether that switch was true or false (on or off), you'd ask:
hh.getOn();
This returns a boolean value, the same value as the isOn field on the object.
You can see this when you call
System.out.println(hh.getOn());
This prints out true or false, depending on whether or not it's set to true or false.
That's how setters and getters work: the setter sets the value of that field, and the getter gets the value of the field.
Now for the (more) fun part.
Since you want to input data, rather than simply outputting data, we have to do something different.
Say I want to have a user type into the console "off" and have it set the households on/off switch to off.
System.out.println(hh); <-- only prints out to console
We need a new object to handle input. Scanner is commonly used for teaching beginners, so we'll use that.
Scanner s = new Scanner(System.in);
This reads data from the system's input stream. You can read about Scanner here.
Now, scanner reads data in as a string using nextLine();
So we'll use that.
String test = s.nextLine();
And of course now we need to test if that string is the same as "off", and if it is, set the isOn field to false (off).
if(test.equals("off") || test.equals("OFF")){
hh.setOn(false);
}
I won't go into more details on how to do the rest of this, such as checking input, looping, etc.
The logic should be in the main method in this application.
Wherever you need to modify the household object is where you need to call those setter/getter methods. The constructor is only ever called when you need a brand new object. If this is still confusing, compare the constructor to setting up a game of monopoly. You initially set up the monopoly board, give everyone their money and starting properties, etc. This is all done so that you can actually play the game. When you lose a property in the game, you would use a setter to remove that property. When you need to see how much money, you'd use a getter.
MonopolyPlayer{
int cash;
MonopolyPlayer(){
cash = 1500;
//we're setting this player up to play the game
}
setCash(int i); //now the player has a new amount of cash
getCash(); // he's checking his account
....etc.
}
And so on.
So to try and break it down.
The idea behind getters and setters is to be able to retrieve and set data on variables inside an object, without having to expose the variables themselves. This means that the fields you have at the top of your class should be declared private. You only want to be able to access them through getters and setters.
In your main method you create an instance of the Household object by using the constructor (you can think of the constructor as the thing which constructs the instance). Your constructor says that to call it, it needs two pieces of data, a String and a boolean. When the constructor is called with these two pieces of data it then stores them in the instance it creates in the fields choice and isOn.
Now that you have your instance of Household (hh), you have an object which contains two pieces of data. If you want to retrieve the data you have stored for one of the variables, you use the getter.
hh.getChoice();
or
hh.isOn();
This will return you the data stored in the choice/isOn field for that specific instance of Household.
If you want to change the data you have stored in hh, you use the setters. So to change the value if isOn you would use
hh.setOn(true);
or
hh.setOn(false);
How would I allow a user to enter into the console to turn the light or the fan on/off?
Using your code, you could do something like this.
public static void main(String[] args) {
System.out.println("Enter On or Off for fan: ");
Scanner scanner = new Scanner(System.in);
String input = scanner.nextLine();
boolean on = false;
if(input.equalsIgnoreCase("yes")) {
on = true;
} else if( input.equalsIgnoreCase("no")) {
on = false;
} else {
System.out.println("Please enter yes or no!");
return;
}
Household fan=new Household("fan", on);
System.out.println(hh);
}
But this isn't really using your setters or getters. You could create your household class like this,
public class Household {
private String choice;//instance variables
private boolean isOn;
public void setOn(boolean isOn) {
this.isOn = isOn;
}
public boolean getOn() {
return isOn;
}
public void setChoice(String choice) {
this.choice = choice;
}
public String getChoice() {
return choice;
}
public String toString() {
return "Choice:" + getChoice() + "\tisOn:" + (isOn() ? "Yes" : "NO");
}
}
And in my code above switch it to:
Household fan = new Household();
fan.setChoice("fan");
fan.setOn(on);
System.out.println(fan);

Creating new classes on code execution

Trying to make code to work with this main:
// TestClass class ResselerTest {
public int ValueOfContainer(Object conatiner, carmodel) { //have to count value of Mazda cars
}
public static void main(String[] args) {
Reseller Joe = new Reseller();
//name cash in k's
Customer John = new Customer("John", 200);
John.get(new Ford(5)); // (i) no of cars. John want to buy 5 ford's
John.get(new Ferrari(5));
John.get(new Mazda(3));
ShoppingCart JohnCart = John.getShoppingCart();
System.out.println("Before payment\n" + JohnCart);
// Hes paying right now!
John.pay();
System.out.println("Paid\n" + John.getShoppingCart());
System.out.println("John got : " + John.getCash() + " USD");
// Now we need to pack them into container
Container JohnContainer = new Container(John);
janek.pack(JohnContainer);
// After packing to conainer.
System.out.println("After packing to conainer\n" + John.getShoppingCart());
// Check whats in container
System.out.println(JohnContainer);
// Lets see how much John paid for white cars.
System.out.println("White cars cost: " +
valueOf(JohnContainer, "white") );
} }
// ---------------------------------------------------------------
class Reseller {
public Reseller() {
// PriceList Singleton!!!
PriceList pl = PriceList.getInstance();
pl.set("Ford", 24);
pl.set("Ferrari", 120);
pl.set("Mazda", 9); //price in k's }
}
//---------------------------------------------------------------
public class Customer { String name; int cash;
public Customer(String name, int cash) {this.name = name; this.cash = cash;
}
public }
//---------------------------------------------------------------
public class ShoppingCart( { //public ShoppingCart // no idea
}
//---------------------------------------------------------------
public class PriceList { public static PriceList instance = null; HashMap<String, Integer> prices = new HashMap<String, Integer>();
public static PriceList getInstance() { if (instance == null) { instance = new PriceList(); } return instance; }
public void set(String car, int value){
prices.put(car, value);
}
// singleton
public PriceList() {
}
}
My main problem.
How to make John.get(new Mazda(3)); to work <sic!>
And how to link cars to color. As far was sad that 1 car have 1 color (Ferrari => ofc. Red :))
I will appreciate any help from you fellows.
It appears that get() doesn't work because you haven't written this bit yet. I suggest you try to write this method (at least the declaration)
It appears you need a structure/class which associates Car and Color.
I suggest you use camelCase for variable names.
I think there is something rather wrong with your object model.
It appears that you have a class for each model of Car. I'd have thought that where needed to be a single Car class, which had attributes such as "model", "color", "price" and so on.
It appears that an instance of (say) Ferrari is supposed to represent a number of cars, rather than a single Car.
I'm not going to tell you exactly how to implement this, since it looks like homework to me.
Well, first of all get Object Oriented concepts clear. What is a person to car relationship.
Secondly, John.get(new Mazda(3)) is not a very good program. The method names should indicate what they do. Here get method is used for actually setting the purchase made by that customer. John buys 3 Mazdas when we call John.get(new Mazda(3)) Is that understanding correct?
The advantage of OOP is that we can map real world entities and talk in real world terminologies in our program. So something like makePurchase(..), submitOrder(..), checkOut(..) would make sense.
It is often said that the programming language helps us think. (sometimes they limit our thoughts :))
Also, a good OO design will say something like a Customer class has a method:
checkOut(Set cars) instead of
checkOut(Honda[] hondaCars)
Does this help?

Categories