Set & Get Methods - java

Java I student here!
I am having a hard time understanding how to make set and get methods. I am working on a question in my textbook Java Programming, 9th Edition independently and I am asked to do the following:
"Create a class named Sandwich. Data fields include a String for the main ingredient (such as tuna), a String for bread type (such as wheat), ad a double for price (such as 4.99). Include methods to get and set values for each of these fields."
It then asks me to do this:
"Create an application named TestSandwich that instantiates one Sandwich object and demonstrates the use of the set and get methods."
So for the first part, I made a .java file with the following code:
public class Sandwich {
private String ingredient;
private String bread;
private double price;
public Sandwich(String ing, String bre, double pri) {
ingredient = ing;
bread = bre;
price = pri;
}
public void setIngredient(String ing) {
this.ingredient = ing;
}
public String getIngredient() {
return ingredient;
}
public String getBread() {
return bread;
}
public Double getPrice() {
return price;
}
}
For the second part, I did the following:
import java.util.Scanner;
public class TestSandwich {
public static void main(String[] args) {
String Ingredient;
String Bread;
Double Price;
Scanner keyboard = new Scanner(System.in);
System.out.println("MAKE A SANDWICH");
System.out.println("Enter an ingredient: ");
Ingredient = keyboard.nextLine();
System.out.println("Enter bread: ");
Bread = keyboard.nextLine();
System.out.println("Enter a price");
Price = keyboard.nextDouble();
Sandwich obj = new Sandwich(Ingredient, Bread, Price);
System.out.println("The ingredient is " + obj.getIngredient());
System.out.println("The bread is " + obj.getBread());
System.out.println("The price is " + obj.getPrice());
}
}
I completed this and it works well, however I realize that I did not create any set methods. Could someone explain to me a better way to do this according to the directions? I'm sure that this way works but I would like to do it by the book and be able to understand it better. I'm not sure where to start with creating the set methods. Please let me know. Thanks so much!
PS: This is NOT homework, I'm just trying to understand this a little better.
-Mark

Here you create an object with these values
Sandwich obj = new Sandwich(Ingredient, Bread, Price);
Here you create an empty object and then set the values
Sandwich obj = new Sandwich();
obj.setIngredient(Ingredient);
obj.setBread(Bread);
obj.setPrice(Price);

Consider this code in your class named Sandwich :
public Sandwich(String ing, String bre, double pri) {
ingredient = ing;
bread = bre;
price = pri;
}
This is called a constructor, a special kind of method that is having the same name as that of the class. But it does not return a value. This constructor is accepting three parameters, of which two are strings and one is a double value. In the constructor body you are actually setting values that are passed to the constructor as parameters and so you can consider this as a setter method which is setting three values at once.
Now consider this code inside the same class :
public void setIngredient(String ing) {
this.ingredient = ing;
}
This method is a setter method which sets only one value, i.e. ingredient. You can create other setter methods as well like this giving any name you want to. For example setBread and setPrice method inside the Sandwich class as follows:
public setBread(String bre) {
bread = bre;
}
public setPrice(double pri) {
price = pri;
}
You can either use the constructor to set the values or the "setter methods"(It is just a normal method that is used to accept and set the values). You can use a single method to set all the values in one go, which is what the constructor is doing or use individual methods to set each values like the setter methods we have defined.
If you are using a single method to set all values at once(in this case the constructor) then during the time of instantiating Sandwich class you need to pass all the values at once to the constructor like you did this :
Sandwich obj = new Sandwich(Ingredient, Bread, Price);
If you do not pass three variables to the constructor at once in the correct order, then compilation error will occur. As you already have a constructor setting three values, the other setter methods are not of great use except when you need to change the values afterwards. I hope this helps.

Simple go like:
System.out.println("Enter another price");
double newPrice = keyboard.nextDouble();
obj.setPrice(newPrice);
and print your obj before / after that call (and of course: #Overwrite toString() on that class to get meaningful output).

Related

Java - User input in a main method and calling setters to main

This is my assignment if you want to read it:
Create a NetBeans project. Create a Java file for EACH of the three classes. For example, add to your project a new file calledBook.java and then create the new class from scratch in that file. Use your UML diagrams as the guideline for writing the code. The variables and methods from the diagrams will be part of each of your classes. Make sure ALL your variables are declared to be private.Protect Your Data!Objects store data or information! When variables are declared private you can protect or guard that information like a Pit Bull protects a piece of meat. Never allow bad data to be stored in your objects!In each 'set' method, make sure the value passed to the method is in range, greater than or equal to the minimum and less than or equal to the maximum. For strings,you may check the length of the string. Each 'set' method should have some sort of 'if-else' statement, assign the data when it is good and print an informative message when an incorrect value is passed. The Shoe class setSize() method would assign the value '10' to the size global variable when it is passed to the method. But, it would print a 'Shoe size must be between 1 and 15' and NOT change the global variable when a value such as '437' was passed to the method. The private variable declarations build a wall around your data, and the 'set' methods are the gates that allow only 'good' information in. Your constructor that assigns values to global variables should use the 'set' methods so you DO NOT have to repeat the same checks in the constructor. The constructor with NO parameters can go ahead and directly set the default values into the global variables.Test Next For each class, create a main method that will declare, build and use an object of that class. So the Book.java main will declare, build and use a Book object, and the other two classes will do the same. Use a command line interface and ask the user to input a value for EACH global variable. Call a constructor or the set methods and insert that information into the object. Once the data is inserted use the object to call the toString method
and print the object to the console. You will be writing THREE main methods, one for each class. When you test, make sure your set methods DO NOT allow bad data into the object. Try to make it fail, see if you can sneak bad values into the variables.To insure you complete each class, use this checklist:_____ Three global variables (not the same type)_____ Two constructor methods_____ Three 'get' methods_____ Three 'set' methods_____ One 'toString' method_____ One main method that creates an object, assigns values, and prints the object
My issue with this is that I have all that is needed except for the user input which i am not sure where to put as well as where to call the set methods because i am not sure how to call those methods in my main. Any help would be greatly appreciated.
This is what I have so far for the first shoe class:
public class Shoe {
private String brand;
private String color;
private int size;
public Shoe() {
}
//every setter should have one check
public Shoe(int size, String brand, String color) {
this.color = color;
this.brand = brand;
this.size = size;
}
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
if(size<1 || size>20){
System.out.println("Invalid");
}
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
if (brand.length()>20 || brand.length()<3)
System.out.println("Invalid Name");
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
if (color.length()>15 || color.length()<3)
System.out.println("Invalid Color");
}
#Override
public String toString(){
return "size is " + this.size + " \nbrand is " + this.brand + " \ncolor is "
+ this.color;
}
public static void main(String[] args){
Shoe s = new Shoe();
System.out.println(s.toString());
}
}
public static void main(String[] args){
Shoe s = new Shoe();
Scanner scan= new Scanner(System.in);
System.out.print("Enter show brand :");
s.setBrand(scan.next());
System.out.print("Enter show color :");
s.setBrand(scan.next());
System.out.print("Enter show Size :");
s.setBrand(scan.nextInt());
System.out.println(s.toString());
}

Is this proper encapsulation for this Java code? I am confused

Does this Java code involving a Book class use proper encapsulation? I feel it can be a lot simpler if I omit some methods but we're required to every method that is in there [especially setters and getters].
Here's the first class:
public class Book
{
private String title;
private double price;
private final double SALES_TAX=0.075;
public String getTitle()
{
return title;
}
public void setTitle(String title)
{
this.title=title;
}
public double getPrice()
{
return price;
}
public void setPrice(double price)
{
this.price=price;
}
public double getSalesTax()
{
return SALES_TAX;
}
public double increasePrice(double incresePrice)
{
return incresePrice;
}
public double calculateSales(double sales)
{
return sales;
}
}
And the second class:
public class BookDriver
{
public static void main(String[] args)
{
Scanner keyboard=new Scanner(System.in);
Book bookOne=new Book();
Book bookTwo=new Book();
bookOne.setTitle("Life of Pi");
System.out.print("Enter number to buy of "+bookOne.getTitle()+": ");
bookOne.setPrice(13.50*bookOne.calculateSales(keyboard.nextDouble()));
bookOne.setPrice((bookOne.getPrice()*bookOne.getSalesTax())+bookOne.getPrice());
System.out.print("Cost for "+bookOne.getTitle()+" $");
System.out.printf("%.2f"+"\n",bookOne.getPrice());
bookTwo.setTitle("Harry Potter: The Goblet Of Fire");
System.out.print("Enter number to buy of "+bookTwo.getTitle()+": ");
bookTwo.setPrice(22.00*bookTwo.calculateSales(keyboard.nextDouble()));
bookTwo.setPrice((bookTwo.getPrice()*bookTwo.getSalesTax())+bookTwo.getPrice());
System.out.print("Cost for "+bookTwo.getTitle()+" $");
System.out.printf("%.2f"+"\n",bookTwo.getPrice());
System.out.print("Enter percent increase of "+bookOne.getTitle()+": ");
bookOne.setPrice((bookOne.getPrice()*bookOne.increasePrice(keyboard.nextDouble()))+bookOne.getPrice());
System.out.printf("Cost of "+bookOne.getTitle()+": $"+"%.2f"+"\n",bookOne.getPrice());
System.out.print("Enter percent increase of "+bookTwo.getTitle()+": ");
bookTwo.setPrice((bookTwo.getPrice()*bookTwo.increasePrice(keyboard.nextDouble()))+bookTwo.getPrice());
System.out.printf("Cost of "+bookTwo.getTitle()+": $"+"%.2f"+"\n",bookTwo.getPrice());
keyboard.close();
}
}
I know that this is a lot so I'm not really expecting much in terms of a response but anything would help. Thanks!!
Let's look at the point of encapsulation. You have a Class which consists of properties and methods. The idea behind encapsulation is, you want the methods in your class to be the only way to change the value (state) of the properties. Think of it like this: if some other code in the program wants to change the value of one of the properties, it cannot do it itself, it must ask a method on the class they reside in to do it. That way, you control access to the properties.
The way this is implemented is with getter and setter methods of which you have created a few. A getter method returns the value of the property and a setter method changes it to a new value.
1.
Your getter and setter methods up to increasePrice() are good. You are preventing access to the properties other than from the methods on your class.
2.
increasePrice() only spits out what was passed into it. It doesn't change the value of any of the properties and thus has no purpose. If you want to be able to increase the price you can change the method like so:
public void increasePrice(double amountOfPriceIncrease) {
price += amountOfPriceIncrease;
/*
price += amountOfPriceIncrease is the same as
price = price + amountOfPriceIncrease
*/
}
3.
This line is a bit troubling. For starters, increasePrice() doesn't do anything other than spit out what was put into it and secondly, there is a lot going on in the one line that makes it complicated and hard to follow.
bookTwo.setPrice((bookTwo.getPrice()*bookTwo.increasePrice(keyboard.nextDouble()))+bookTwo.getPrice());
You dont necessarily need all the setters. For example, its probably reasonable to assume that a book has a title, and it doesnt change. So you can make it final, omit the setter, and pass it into the constructor.
Also, think about how you're modelling things. Is sales tax a property of a book? I'd say not.
Because all the required variables title, price for class Book are set to private, and that access can only be used using get..(), and changing it if possible can only be used using set..(some variable) or an instance method affecting one of the fields, it demonstrates proper encapsulation, so all getting and setting are regulated.
However, I spotted several mistakes in BookDriver, namely with the improper usage of Book fields.
The price should change only through setPrice or increasePrice.
You should also implement getPriceAfterTax to determine after-tax prices for a book.
The total cost of the books you bought should not involve any setPrice.
There is a mistake with public double calculateSales(double sales). It does nothing but returns back sales. The calculateSales should calculate the total cost of the book(s) being bought, using one int variable, and you also resorted in changing the price of these books, which shouldn't happen. It is the reason why you wrote messy code, as in the excerpt
bookTwo.setPrice(22.00*bookTwo.calculateSales(keyboard.nextDouble()));
bookTwo.setPrice((bookTwo.getPrice()*bookTwo.getSalesTax())+bookTwo.getPrice());
This avoids the potential case of changing the values of that BOOK object to unexpected or unusual values and value combinations.
Additionally, SALES_TAX can be made into a public static final double instead, as it is assumed to never change, and you can simply obtain SALE_TAX without requiring getSalesTax().
The last two methods do not make much sense. You simply return what you put in. Do it this way:
public double increasePrice(double increase)
{
price *= increase;
}
public double calculateSales(double sales)
{
//return {your formula}
}

How can a string be used to call an object method in Java?

I have a class called "Skill" with a getName() method. I use it to return the name of the Skill objects that I create. When I try to compile my code, it says "Cannot find symbol- method getName()". Is there any way to get around this? For example, in my main method:
String[] playerSkill = new String[1];
playerSkill[0] = "a";
System.out.println(playerSkill[0].getName());
And in my Skill class:
public Skill(String n, String d, int p) {
name = n;
description = d;
power = p;
}
public String getName() {
return name;
}
I know I cannot make the String look like a Skill object:
System.out.println((Skill)playerSkill[0].getName());
The main problem is that the arrays are to be filled with user input so the arrays need to be String arrays. How would I get around this?
Your method getName is from class Skill and you try to invoke it from String class.
You should do something like this:
Skill[] playerSkill = new Skill[1];
playerSkill[0] = new Skill("name", "desc", 3);
System.out.println(playerSkill[0].getName());
When you are saying String[] playerSkill = new String[1]; That means that the array created is of String type and you ll only be able to call methods of String class. The element at playerSkill[0] can only hold object of String and not Skill
I think you want to achieve this
Skill[] playerSkill = new Skill[1];
playerSkill[0] = new Skill("a", "b", 0);
System.out.println(playerSkill[0].getName());
Since you mentioned you need to take input and then make the skill object. You can get the string, int from the console and then create the instances of Skill
Scanner sc = new Scanner(System.in);
String name = sc.next();
String desc = sc.next();
int x = sc.nextInt();
Skill s = new Skill(name, desc, x);
you need to modify these lines according to your stuff
Since the String object doesn't have a getName method attached to it, Java isn't going to allow you to call it on an instance of it.
Use the object that has the method attached to it. Instead of an array though (since you only create one space in it), just go with a regular instance.
Skill skill = new Skill("name", "desc", 10);
System.out.println(skill.getName());
This is important to note because you may run into situations in which other objects will have similarly named methods, but not give you the behavior you want. Always be specific about the type of object you're interacting with.
If you need such a behavior I suggest to create a POJO such as:
public class Player{
private String skill, name;
public setSkill(String skill){
this.skill = skill;
}
public getSkill(){ return this.skill;}
public setName(String name){
this.name=name;
}
public getName(){return this.name;}
}

Error Cannot be applied to given types

Code:
public void checkHitDiscount(WineCase wineCase1)
{
if(hits%10==0)
{
wineCase1.setPrice()=0.9*wineCase1.getPrice;
System.out.println("Congratulations! You qualify for 10% discount.");
} else
System.out.println("You do not qualify for discount.");
}
The error I get here is:
Method setPrice cannot be applied to given types. required double,
found no argument.
I am trying to get a price field in the WineCase class modified. It is a double.
setPrice() is a method. You seem to also have a method called getPrice(), and these both probably corresponded to an instance variable called price within your object.
If price is private, then you call getPrice() as such:
wineCase1.getPrice();
This returns a double (assuming price is of type double).
And again, if price is private, then you'll need to set it as such:
wineCase1.setPrice(somePrice);
So in you're above example, if you want to set price to 90% of what it's currently at, the proper syntax would look like this:
wineCase1.setPrice(0.9*wineCase1.getPrice());
Alternatively, you could potentially write a public method for this class that looks like this:
public void discountBy(double disc) {
price *= 1.0 - disc;
}
// or like this:
public void discountTo(double disc) {
price *= disc;
}
// or both...
To use this method and apply a 10% discount to wineCase1, you'd do this:
wineCase1.discountBy(0.1);
// or like this:
wineCase1.discountTo(0.9);
Then you'll still use:
wineCase1.getPrice();
To retrieve the private variable, price, from the object.
And finally, this might potentially be the best solution, add these methods:
public double getPriceDiscountedBy(double disc) {
return price*(1.0-disc);
}
public double getPriceDiscountedTo(double disc) {
return price*disc;
}
These methods will allow you to retrieve the value of the discounted price without changing the original price of the item. These would be called in the same place you'd get a getPrice, but take a discount argument to modify only the returned price. For example:
double discountedPriceOutsideOfObject = wineCase1.getPriceDiscountedTo(0.9);
//or like this:
double discountedPriceOutsideOfObject = wineCase1.getPriceDiscountedBy(0.1);
If price field is double type then you simply do like below.
public void checkHitDiscount(WineCase wineCase1)
{
if(hits%10==0)
{
wineCase1.setPrice(0.9*wineCase1.getPrice());
System.out.println("Congratulations! You qualify for 10% discount.");
} else
System.out.println("You do not qualify for discount.");
}
And in WineCase.java the setPrice must be like below.
pubilc void setPrice(double price) {
this.price = price;
}
You cannot assign any value to methods, but method can return values.

accessing an object array item, java

I have created a number objects using an array statement, and I can println the values passed within the class as it is created, but when I try and retrieve element values from outside of the class (monopolygame class) it doesn't recognise the refrence - how can I refrence this correctly?
public class monopolygame {
public static void main(String[] args) {
//set up array of 18 objects
property properties[] = new property[18];
//create 18 property objects and populate array
properties[0] = new property("a","available",400,500);//create property
properties[1] = new property("b","available",400,500);//create property
properties[2] = new property("c","available",200,300);//create property
properties[3] = new property("d","available",100,180);//create property
properties[4] = new property("e","available",400,700);//create property
}
}
property class...
public class property
{
public static void main(String[] args)
{
}
//constructor
public property(String propertyname, String owner, double price, double rent)
{
System.out.println("Property info for " + propertyname
+ " - Rent : £" + rent
+ "Price : £" + price
+ "owned by :" + owner);
}
}
I am using this kind of reference in the monopoly class to try and access the data
if (properties[2].propertyname == "available")
{
System.out.println("avaialble");
}
else
{
System.out.println("sold");
}
Thanks
You have to declare those attributes in the "property" class first:
class property {
String propertyname;
String owner;
int price;
int rent;
public Property( String somename, String owner, int price, int rent ) {
this.propertyname = somename;
this.owner = owner;
this.price = price;
this.rent = rent;
// and so on
}
}
The array you're using is local to the main method.
To access it outside of the scope of the main method you should declared either as a class attribute or as an instance attribute like this:
public class monopolygame {
public static property properties[];
public static void main(String[] args) {
//set up array of 18 objects
properties = new property[18];
.....
That way you can access the array in other method like this:
public void setUp() {
for( property p : properties ) {
System.out.println( p.propertyname ); // etc.
Then your code:
if (properties[2].propertyname == "available")
Will work.
BTW in Java all the class name start with uppercase by convention , so it should be:
Property instead of property and MonopolyGame instead of monopolygame
Given the code you've supplied us with, it doesn't look like you're actually storing the values passed in to your property constructor. Here's something a bit closer to what your property class should look like:
public class property
{
private String propertyname;
private String owner;
private double price;
private double rent;
public String getPropertyName()
{
return propertyname;
}
public void setPropertyName(string newName)
{
propertyname = newName;
}
// more getter/setter methods here
public property(String propertyname, String owner, double price, double rent)//constructor
{
this.propertyname = propertyname;
this.owner = owner;
this.price = price;
this.rent = rent;
System.out.println("Property info for " + propertyname + " - Rent : £" + rent + "Price : £" + price + "owned by :" + owner);
}
}
A few remarks:
In Java, string comparisons need to
be done with the equals() method, not
==. See this link for an explanation of why using == might work in some cases, but that shouldn't be expected.
It is a convention to capitalize class names -> Property rather than
property.
Avoid mixing and matching bracket positioning. Use at the end of the same line or at the beginning of the next line, but not both. The most frequent use is at the end of the same line.
You need to add a public method to access the internal of monopolygame class. That is the main aspect of your question.
But in general your code is not the correct way of doing things in Java. Class names must be capitalized, for example. An empty main in the second class is pointless. You need to learn more about the basic Java stuff, I answer your question because I think you could learn a lot here, but I suggest you to check the trails covering the basics on The Java Tutorial.
Two problems are immediately obvious:
You're not storing the arguments passed to the property constructor in fields within that class.
Once you do that, you're trying to compare strings by reference (or by identity, via ==) rather than by value (via String#equals(String)). Unless you've interned the strings via String#intern(), two different String instances with the same character content will not compare as equal via ==. That comparison only looks at the memory addresses of the object references, which will most likely point to two different String instances, each with a different address.
As this question looks like a homework assignment, please tag it as such.

Categories