Manipulating Variables using Setters and Getters - java

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);

Related

Accessing an object of a class from another class object

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!

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 to get variables from different classes?

So i'm working on this project and i'm having trouble moving variables from one class to the other. The goal of this tiny software is to have the user input 2 pieces of information, one's a string and the other is an int. I also have 2 classes, one to retrieve the information and the other one to calculate it.
This is the first class called Software:
import java.util.Scanner;
public class Software
{
public Scanner softwareName;
public Scanner devicesAmount;
public Software()
{
devicesAmount = new Scanner(System.in);
softwareName = new Scanner(System.in);
}
/**
*Gets the information from the user to later on process
*/
public void InfoGet()
{
Devices findDevices= new Devices();
Devices findNumber= new Devices();
String softwareName;
int devicesAmount;
Scanner sc= new Scanner(System.in);
System.out.println("Welcome to the Software License Calculator");
System.out.println("Please type in the name of the Software:");
softwareName = sc.nextLine();
System.out.println("");
System.out.println("Please type in the number of devices that have the software:");
devicesAmount=sc.nextInt();
findDevices.Calculations(devicesAmount);
findNumber.getNewDevices();
sc.close();
System.out.println(softwareName+ " & "+ findNumber);
}
}
And here's the second class called Devices:
public class Devices
{
public int NewDevices;
public String softwareName;
/**
* Gets number of Devices to preform the calculations of removing 1000 users
*/
public static void Devices()
{
Software getDevices= new Software();
getDevices.InfoGet();
}
public void Calculations(int devicesAmount){
if (devicesAmount>=1000){
NewDevices= devicesAmount - 1000;
}
else{
NewDevices=devicesAmount;
}
}
}
dunno why I post as user when I'm on my movil device, but to the point:
First of all in the class Software you have 2 objects "Device", following the MVC arquitecture you should only declare 1 controller object for the view class, to start I recommend you to only declare 1 Device for Software class, like this and we're gonna make the variables protected just cause they should be private or protected to respect the encapsulation:
public class Software {
protected Devices devices;
protected Scanner softwareName;
protected Scanner devicesAmount;
... }
I recommend you to do the same for the Devices class variables.
Then we're gonna build a proper constructor for Devices class so we can move the values through classes:
public Devices (String softwareName) {
this.softwareName = softwareName;
this.newDevices = 0;
}
So we can have this values at the Devices class. Then we need to add the getter for newDevices and adding the toString method to the Devices class so you can print the object.
public int getNewDevices() {
return newDevices;
}
public String toString() {
return softwareName + " & " + newDevices;
}
Then we're gonna move some stuff at the Software InfoGet method to build de devices correctly and printing it.
public void InfoGet() {
String softwareName;
int devicesAmount;
Scanner sc= new Scanner(System.in);
System.out.println("Welcome to the Software License Calculator");
System.out.println("Please type in the name of the Software:");
softwareName = sc.nextLine();
System.out.println("");
System.out.println("Please type in the number of devices that have the software:");
devicesAmount=sc.nextInt();
devices = new Devices(softwareName); // So we initialize the object.
devices.Calculations(devicesAmount);
sc.close();
System.out.println(devices.toString()); // Here we just call the toString() method we build to print the values.
}
We didn't use the getNewDevices() method, but building getters and setters for controller classes is a good practice in general ;).
I highly recommend you to read about MVC (model-view-controller) if you wanna build your proyect in a "standar" way.
To solve your problem you can add to each class the getters and setters for each variable you need to move so you can move values between classes.
Like this for setters:
public void setValue(Object value) {
this.value = value;
}
And this for getters:
public Object getValue() {
return this.value;
}
It's very confusing between Scanner, Device, Software, classes and objects with the same name upper or lower cases.
I should recommend to rename you classes and variable clearly.
Some further advices:
why keeping Scanner as variables ? It's not data, it media to get it.
why note keeping data ? like softwareName (Scanner AND String).
I would
add two variables (softwarename and amount), private
keep them
add methods to Set and Get
Calculations() (and others) won't compile. Probably you need to add an argument to that method and you are done (?):
public void Calculations(int devices2){
...

Finding object in ArrayList via user input - Java

I'm trying to display Car from fleet ArrayList using user input. Unfortunately I'm not sure how to go about it. I have found few examples online but cannot make them work. I have incorporated following method:
void findRegNo(String reg){
boolean exist=false;
for(int i=0;i<this.fleet.size();i++){
if(this.fleet.get(i).getRegNo() == reg){
exist=true;
break;
}
}
if(exist) {
System.out.println("!!!!!");
} else {
System.out.println("xxx");
}
}
At the moment the result is always: xxx so the code does not find any match. That function is placed in my container class, I was thinking that maybe it supposed to be in different location.
These are variables of Car class:
public class Car {
//defining variables
String regNo;
String model;
double mileage;
Strings are objects, not primitives. Hence, you should use equals to compare their value, not ==, which checks that both references are to the same object:
if (this.fleet.get(i).getRegNo().equals(reg)) {
exist = true;
break;
}

How do I separate the choices in a list

The purpose of the program is to calculate the volumes of different geometrical figures (Like a cylinder or a pyramid). I've started out by adding a list where the user can choose between the different figures.
The problem is that I don't know how to make the program know which formula to use. I need to be able to separate the choices instead of just making an int out of the answer.
private void btnAktiveraActionPerformed(java.awt.event.ActionEvent evt) {
String form = listForm.getSelectedValue().toString();
int fo = Integer.valueOf( form );
String höjd = txfHöjd.getText().toString();
int hö = Integer.valueOf( höjd );
String bredd = txfBredd.getText().toString();
int br = Integer.valueOf( bredd );
String radie = txfRadie.getText();
int ra = Integer.valueOf(radie);
String djup = txfDjup.getText();
int dj = Integer.valueOf(djup);
double ACyl = 3.14*ra*ra*hö;
double APyr = (br*dj*hö)/2;
double AKub = br*dj*hö;
double ARät = br*dj*hö;
txfHöjd.setEnabled(false);
txfBredd.setEnabled(false);
txfDjup.setEnabled(false);
txfRadie.setEnabled(false);
listForm.setEnabled(false);
}
private void btnBeräknaActionPerformed(java.awt.event.ActionEvent evt) {
// I know this code won't work, its just a reminder.
if (answer == Cyinder){
System.out.print("volymen är: "+ACyl+" cm^3");
}
}
I don't understand your question very clearly. I would suggest to make a plan to solve your problems.
make a list of figures that program will calculate
make a list of methods to count volumes of those figures
create individual classes, variables etc...
create methods
create main method with user input
You mentioned you don't know which formula to use. I assume there won't be many formulas in your program. I would create an individual method for each individual figure i.e. piramidFormula(), cilinderFormula()...
There is no point to refer to polimorphism when I think your level of programming is very basic at this stage.
I hope that will help you a little bit.
You need a list to hold the things, you seem to understand this just fine.
You need a way to select things. Selection is typically not exactly the same thing as the list, you need a class to be responsible for the "selection" behaviour.
Each thing has a routine that can calculate the volume. That means it will need input parameters. This is where it starts to get tricky, because if you want all of your things to be in the same list, you need to decide how to manage the different input parameters for the different types in the list.
public List<VolumeCalculations> volumeCalculations ...
public interface VolumeCalculation {
public double getVolume();
}
public class CubleCalcuation implements VolumeCalculation {
private double side = 0;
public void setSide(double value) {
this.side = value;
}
#Override
public double getVolume() {
return side*side*side;
}
}
the other volume calculations are left as an exercise to you.
Then you need to put them all in the list
volumeCalculations.add(new CubeVolumeCalculation());
...
But when you select the calculation, you will need "something" to ask for the right input.
public interface CalculationInputGather {
public void setCalcualtion(VolumeCalcuation value);
public void askForInputs();
}
which the one for the CubleCalcuation might look like
public CubeInputGather implements CalculationInputGatherer {
#Override
public void setCalculation(VolumeCalcualtion value) {
if (value instanceof CubeCalcuation) {
this.volume = value;
}
throw new IllegalArgumentException("value must be a CubeCalculation");
}
public void askForInputs() {
System.out.println("enter the side value:");
// read the value
volume.setSide(value);
}
}
then when you know the selected item in the list, you can use a Map of Calcuations to their input gatherers to lookup the right input gatherer for the selected calcuation.
If you already have the list for the user to choose from, maybe consider a map instead. You can have all your shapes as the keys of the map and then the formulas for volume as the values of the map. The list of shapes can be provided to the user via the keySet and their response can be matched back against the map to find the formula.
EDIT: You have your formulas for each shape inside an action event. You'll need to move those into a separate class
public static class Formulas() {
// list all formulas here
private String cylinder = "3.14*r*r*h";
}
Then when you hit the action you can either create a new instance of the Formulas class and use any convenience methods you might write in there.

Categories