I keep getting the
The method add(BigDecimal) in the type BigDecimal is not applicable for the arguments (pay)"
error with the code below.
For reference I have saved the pay class in a separate file, where I import BigDecimal as well.
Would one of you like to point out where I'm lacking/misunderstanding? I've tried to find a solution, but I couldn't find something.
import java.util.Scanner;
import java.math.BigDecimal;
class SalesPreInt {
public static void main(String[] args) {
Pay pay = new Pay();
pay.basePay();
BigDecimal intCalc = new BigDecimal("0.15");
Scanner userInput = new Scanner(System.in);
System.out.println("What were your total sales?");
BigDecimal salesPre = userInput.nextBigDecimal();
System.out.println("You're Total Sales were "+salesPre);
userInput.close();
BigDecimal postIntCalc = salesPre.multiply(intCalc);
BigDecimal salesCom = postIntCalc.add(salesPre);
int finalCalc = salesCom.add(pay);
System.out.println("Your total sales including commission is "+salesCom);
System.out.println("Your total pay is"+finalCalc);
}
}
pay.java file below:
import java.math.BigDecimal;
public class Pay {
public void basePay() {
int basePay = 50000;
BigDecimal bd = new BigDecimal(String.valueOf(basePay));
}
}
Like the error message tells you, the add method of BigDecimal with one argument expects a BigDecimal instance: [javaDoc]
public BigDecimal add(BigDecimal augend)
Returns a BigDecimal whose value is (this + augend), and whose scale
is max(this.scale(), augend.scale()).
Parameters:
augend - value to be added to this BigDecimal.
Returns:
this + augend
You've passed a variable of type Pay to this method and since Pay is not a subtype of BigDecimal it is not related to it. The method add can't know how to add a Pay instance, the compiler complains about that argument type.
You can do the following fix, to bypass that problem:
Your basePay method creates a BigDecimal and I guess this is the one you like to add to salesCom, so change that method a bit:
public BigDecimal basePay() {
int basePay = 50000;
return new BigDecimal(String.valueOf(basePay));
}
This method now creates a BigDecimal and returns it to the calling method. Now change the add method call to use the basePay method:
int finalCalc = salesCom.add(pay.basePay());
Now there is only one problem left. As you can see in the JavaDoc posted above, add returns a new BigDecimal instance, but you're assigning the returned value to the variable finalCalc, which is of type int. So we need to change it to BigDecimal:
BigDecimal finalCalc = salesCom.add(pay.basePay());
Now your code compiles and it should work as expected.
If you want the Pay class to return a basePay value, you need a proper method for that, ie a method that actually returns the value, ie not a void method.
public class Pay {
private int basePay = 50000;
public BigDecimal getBasepay() {
// no need to pass via strings, BigDecimal has a constructor that takes an int value
BigDecimal bd = new BigDecimal(basePay);
return bd;
}
}
which will be called like
int finalCalc = salesCom.add(pay.getBasepay()).intValue();
as you want to store the result as an integer, or
BigDecimal finalCalc = salesCom.add(pay.getBasepay());
Notice that I declared basePay - the value - as a private member of the Pay class, and renamed the method to start with get (called a getter in Java, and by convention their names are prefixed with get). If some day you need a way to modify that value, just add a setter
public void setBasepay(int bp) {
basePay = bp;
}
And maybe you also want to be able to set the value directly as a BigDecimal although it's stored as an int? Just add
public void setBasepay(BigDecimal bp) {
basePay = bp.intValue();
}
Two methods with the same name but other arguments is called overloading, and that's an often-used mechanism to introduce flexibility and versatility in your programs.
I would also suggest you have a look at a good tutorial, the official one by Oracle is pretty good (and free :))
Related
public static void main(String[] args) {
Double ans1 = add(5, 9);
Number ans2 = add(new Integer(3), new Double(2.4));
double ans3 = add(10, 3.2);
System.out.println(answer1 + " " + answer2 + " " + answer3);
}
Given the main method above, how would I create a static method (as opposed a set of overloaded methods) which in turn would could successfully call the methods within the main?
Thanks in advance!
write a single static method (not a set of overloaded methods) which
can be called successfully by all the methods in main.
It is very basic, you can simply do that by creating a new static add() method (a single method contains the code for all calls to different overloaded add methods) as below:
public static void main(String[] args) {
add();
}
public static void add() {
Double ans1 = add(5, 9);
Number ans2 = add(new Integer(3), new Double(2.4));
double ans3 = add(10, 3.2);
System.out.println(answer1 + " " + answer2 + " " + answer3);
}
OK. I think I understand what your teacher wants, despite the wrong terminology he's using. He wants you to write a unique static add() method. And the code should compile and run after this unique add() method is being added to the code.
Since the method is called with arguments that are of type int, Integer, Double and double, the argument types must be a parent class of all these types (after boxing/unboxing). For example Number, or Object.
Since the returned value is assigned to a variable of type Double, Number and double, the return type must be a common class or subclass subclass of all this (after boxing/unboxing).
A candidate would thus be, for example:
private static double add(Object i, Object i1) {
return 0;
}
Of course, the ansX variables need to be renamed to answerX, too, otherwise the code will never compile.
I guess we can also safely assume that add() should add the arguments. I leave that as an exercise for your.
In order for the add method to be called successfully by the main method, you need to figure out what types to use for the return value and the parameters.
Here's a template:
private static ??? add(??? a, ??? b) {
return a + b;
}
As you can see, main calls add with all kinds of arguments, and it stores the result in different types of variables as well.
If you analyze the main method, you will see that the add method must be able to accept the following types of parameters:
(int, int)
(Integer, Double)
(int, double)
It can be deduced that an int, a double, an Integer and a Double can be implicitly converted to the parameters' type. If you do a little bit of thinking, you will know that double is one of the types that satisfy this requirement. This means that the parameters can be of tyoe double!
And it must be able to return a value that's compatible with the following types:
Double
double
Number
It can be deduced that the return type must be able to be implictly converted to Double, double, or Number. double also satisfy this requirement. This means that the method returns a double as well!
Here's the completed method:
private static double add(double a, double b) {
return a + b;
}
Okay so don't get turned off by the fact that I want homework help.
Anyways, I don't want to explain the entire project for this little bit of help, but I'll just list some rules, and what I did with them. They're in weird order and they don't make complete sense. And there are many ways to do this probably, and I simply don't know what is what.
So here's the rules I'm confused about:
Three fields, a String for name of the purchase, int for units purchased, and a double for cost per unit.
So I made this:
private String purchase = "";
private int unitsPurchased = 0;
private double costPerUnit = 0;
Then, next rule:
Standard accessors and modifier methods for each field, so I made this:
//Accessors
public String purchase(){
return purchase;
}
public int unitsPurchased(){
return unitsPurchased;
}
public double costPerUnit(){
return costPerUnit;
}
//Modifiers
public void setPurchase(String purchase){
this.purchase = purchase;
}
public void setunitsPurchased(int unitsPurchased){
this.unitsPurchased = unitsPurchased;
}
public void setCostPerUnit(double costPerUnit){
this.costPerUnit = costPerUnit;
}
Then this: Negative values are not allowed, so change those to zero in all cases.
Wasn't sure if that meant to do anything, so I continued on.
Then this: Constructor to initialize these three fields (String, int, double) in that order.
So I did this:
public Purchase(String initialPurchase, int initialUnitsPurchased, double initialCostPerUnit){
purchase = initialPurchase;
unitsPurchased = initialUnitsPurchased;
costPerUnit = initialCostPerUnit;
}
Then this rule: Constructor overload, (String, double) assumes the int quantity is zero.
I didn't know if that meant anything, so once again I skipped it
Then this rule: Default constructor that assumes name is “” and numbers are zero, must call the three argument constructor.'
Now I'm just confused. So first of all, I would like to know if my code seems right. I don't think I need to explain the backstory of the program to do that. Then, I would love to know what to do about that last rule, because it says "must call the three argument constructor" am I supposed to use "this"? I didn't know where to go and I've tried a couple ideas but I don't think it works. I can't test to see if it's right either, given there's not really anything to test. Thanks so much to anyone who helps.
Here's just everything I've written:
public class Purchase {
private String purchase = "";
private int unitsPurchased = 0;
private double costPerUnit = 0;
//Accessors
public String purchase(){
return purchase;
}
public int unitsPurchased(){
return unitsPurchased;
}
public double costPerUnit(){
return costPerUnit;
}
//Modifiers
public void setPurchase(String purchase){
this.purchase = purchase;
}
public void setunitsPurchased(int unitsPurchased){
this.unitsPurchased = unitsPurchased;
}
public void setCostPerUnit(double costPerUnit){
this.costPerUnit = costPerUnit;
}
//Default constructor
public Purchase(){
purchase = "";
unitsPurchased = 0;
costPerUnit = 0;
}
//first constructor
public Purchase(String initialPurchase, int initialUnitsPurchased, double initialCostPerUnit){
purchase = initialPurchase;
unitsPurchased = initialUnitsPurchased;
costPerUnit = initialCostPerUnit;
}
//constructor overload
//Default constructor
}
You don't really need that but just in case. That's all a mess, not sure what I'm writing. But thanks to anyone that helps.
Starting with the first rule you didn't understand:
Negative values are not allowed, so change those to zero in all cases.
This is referring to the setter methods you wrote, and it means that if someone calls setUnitsPurchased with a negative number as a parameter, you only set unitsPurchased = 0.
You'll probably want to add an if statement (or ternary, if you're familiar with those) to setUnitsPurchased and setCostPerUnit checking for values below zero.
Wasn't sure if that meant to do anything, so I continued on. Then this: Constructor to initialize these three fields (String, int, double) in that order.
Instead of directly setting the values (like you did):
purchase = initialPurchase;
unitsPurchased = initialUnitsPurchased;
costPerUnit = initialCostPerUnit;
You should probably call your setters, so you don't have to repeat your checks:
this.setUnitsPurchased(initialUnitsPurchased);
// etc.
Constructor overload, (String, double) assumes the int quantity is zero.
If a class has an overloaded constructor, it means that you can initialize it with different amounts and/or types of parameters. You've already overloaded the constructor with an empty constructor and one that takes three arguments.
Simply make another constructor, but with this signature:
public Purchase(String initialPurchase, double initialCostPerUnit)
Default constructor that assumes name is "" and numbers are zero, must call the three argument constructor.
Instead of the default constructor you implemented, you must call the three argument constructor. To call another constructor, use the this keyword, and invoke it like a method, passing in the correct parameters:
this("", 0, 0);
Happy Coding!
Couldn't be more self-explanatory. It writes itself if you can read:
public class Purchase {
private String purchase;
private int numUnits;
private double costPerUnit;
public Purchase() {
this("", 0, 0.0);
}
public Purchase(String purchase, double costPerUnit) {
this(purchase, 0, costPerUnit);
}
public Purchase(String purchase, int numUnits, double costPerUnit) {
this.purchase = purchase;
this.numUnits = (numUnits < 0) ? 0 : numUnits;
this.costPerUnit = (costPerUnit < 0.0) ? 0.0 : costPerUnit;
}
// Leave the rest for you.
}
Three fields, a String for name of the purchase, int for units purchased, and a double for cost per unit.
You got it correct, though there is no need for assigning any values to the data members.
private String purchase;
private int unitsPurchased;
private double costPerUnit;
Standard accessors and modifier methods for each field
You got this correct too.
Negative values are not allowed, so change those to zero in all cases.
You need to change your code to convert neg values to zero. e.g.
public void setunitsPurchased(int unitsPurchased){
if(unitsPurchased < 0)
unitsPurchased = 0;
this.unitsPurchased = unitsPurchased;
}
Constructor to initialize these three fields (String, int, double) in that order.
You got this correct. Though you might want to have this keyword for data members. It just makes it more readable.
public Purchase(String initialPurchase, int initialUnitsPurchased, double initialCostPerUnit){
this.purchase = initialPurchase;
this.unitsPurchased = initialUnitsPurchased;
this.costPerUnit = initialCostPerUnit;
}
Constructor overload, (String, double) assumes the int quantity is zero.
This is simple. you want a constructor with just 2 arguments. It also specifies to have unitsPurchased set to 0.
public Purchase(String initialPurchase, double initialCostPerUnit){
this.purchase = initialPurchase;
this.unitsPurchased = 0;
this.costPerUnit = initialCostPerUnit;
}
Default constructor that assumes name is “” and numbers are zero, must call the three argument constructor.'
Now you know a default constructor does not take any arguments. but the question asks to call the three argument constructor from within this constructor. that can be done using the this() as follows:
public Purchase(){
this("", 0, 0.0);
}
So I am super new to programming in general and I'm only a few weeks into a beginning summer course on Java and I'm super confused on this assignment for a simple java calculator that we need to use three classes in.
I decided to write the code and get "working" in one class and then try and split it up into the necessary multiple classes. However, I'm having trouble doing that. I guess I'm more confused then I thought I was on how methods and parameters work. I'd greatly appreciate any help explaining how they work particularly in this program or something similar so that I can understand it more clearly.
Here are a part of the instructions that I'm having a hard time with....
"The Driver class is the only class wit hmain(String[] args)method.Driver class should call a method in the Menu class to print the menu, and from that method there should be calls to methods in Actions class for respective functionality from the menu."
The Menu class and the method calls are working correctly and I planned on basically adding the rest to the Action class but I just keep confusing myself more every time I mess with it. I don't know if it makes a difference but I thought about adding the switch to the Menu class, also if I do, do I need to make it a method to call the switch? How would that work?
import java.util.Scanner;
import java.io.*;
public class Driver {
public static void main(String[] args) {
String s1 = Menu.getInput("Enter a numeric value: ");
String s2 = Menu.getInput("Enter a numeric value: ");
String option = Menu.getInput("Enter: \n 1=Add \n 2=Subtract \n 3=Multiply \n 4=Divide");
class Action {
int optionInt = Integer.parseInt(option);
double result = 0;
switch (optionInt) {
case 1:
result = addValues(s1, s2);
break;
case 2:
result = subtractValues(s1, s2);
break;
case 3:
result = multiplyValues(s1, s2);
break;
case 4:
result = divideValues(s1, s2);
break;
default:
System.out.println("You entered an incorrect value");
}
public static String(
System.out.println("The answer is " + result);
}
private static double divideValues(String s1, String s2) {
double d1 = Double.parseDouble(s1);
double d2 = Double.parseDouble(s2);
double result = d1 / d2;
return result;
}
private static double multiplyValues(String s1, String s2) {
double d1 = Double.parseDouble(s1);
double d2 = Double.parseDouble(s2);
double result = d1 + d2;
return result;
}
private static double subtractValues(String s1, String s2) {
double d1 = Double.parseDouble(s1);
double d2 = Double.parseDouble(s2);
double result = d1 - d2;
return result;
}
private static double addValues(String s1, String s2) {
double d1 = Double.parseDouble(s1);
double d2 = Double.parseDouble(s2);
double result = d1 + d2;
return result;
}
}
}
class Menu {
public static String getInput(String prompt) {
String option;
Scanner scan = new Scanner(System.in);
System.out.println(prompt);
return option = scan.nextLine();
}
}
Thanks for any help!!
Scott
I think this is what you probably looking for :
import java.util.Scanner;
import java.io.*;
public class Driver {
public static void main(String[] args) {
// get the Menu instance & call the method to get the menu list
Menu m = new Menu();
m.getMenu();
}
}
Note: Note here inorder to call a method that resides in another class you first need to get instance of the class and then on that instance you need to invoke the method. Like in the above m.getMenu()
In Menu class you need to write the following logic :
class Menu {
public void getMenu() {
// take the user inputs and write your validation and proper conversion logic e.g 'int' or 'double' what ever you want
Scanner s = new Scanner(System.in);
System.out.println("Enter the first number :");
double num1 = s.nextDouble();
System.out.println("Enter the second number :");
double num2 = s.nextDouble();
System.out.println("Please select an operation :");
System.out.println("1 - Add " + "\n" + "2 - Subtract" + "\n"
+ "3 - Multiply" + "\n" + "4 - Divide");
int choice = s.nextInt();
Double result;
Action service = new Action();
switch (choice) {
// call the appropriate method based on user selection
case 1:
result = service.addValues(num1, num2);
service.displayResult(result);
break;
case 2:
result = service.subtractValues(num1, num2);
service.displayResult(result);
break;
case 3:
result = service.multiplyValues(num1, num2);
service.displayResult(result);
break;
case 4:
result = service.divideValues(num1, num2);
service.displayResult(result);
break;
default:
System.out.println("Your choice is invalid.");
}
}
}
NOte: Here you're doing nothing but taking the user inputs and passing those inputs as parameter to the appropriate methods. (Again note here, how the methods are being invoked).
In Action class put your service logic
class Action {
public double addValues(double a, double b) {
return a + b;
}
public double subtractValues(double a, double b) {
return a - b;
}
public double multiplyValues(double a, double b) {
return a * b;
}
public double divideValues(double a, double b) {
return a / b;
}
public void displayResult(double result) {
System.out.println("Result is :" + result);
}
}
Note: Here each method serves a very different purpose. When you invoke any method on the instance of this class by passing your user inputs as parameter then it simply serve its purpose.
P.S:
Methods are much like your behaviors. Simply consider yourself as a machine. Now when you get thirsty you drink water, right? so here is your brain that is the main() instructing your hand to perform some task much like you're invoking a method to serve a purpose here. (I don't know how far I able to give a clarity of this, but I hope this will be helful to you in some extent :) )
Firstly, I'd recommend a good book, or failing that, look through Oracle's resources such as this...
Java is an object oriented language. An object is an INSTANCE of a class. Think of classes like modules, that are logically separated and in theory should be runnable and logical not only in the environment which you create it, but in other scenarios as well.
For example, you may have a program called Car Park, which is the driver (contains the main method, the entry point to a Java program). You then have a class called Car, and a class called Person. A class should contain variables and method related to that class. So in the Car class, you may have variables such as colour, noOfWheels, noOfSeats etc. The car class may also contain methods to 'do things' associated with the class, such as updateColor() or changeNoOfWheels().
In regards to methods and parameters, it is really quite simple.
When a method is defined as such:
public void updateColor(Color newColor)
{
color = newColor;
}
The Color that is being passed inbetween the brackets is called the formal parameter. It defines the type that is required when the method is actually called. This can be any type, depending on what your method does. A method that adds two integers may accept (int x, int y as its parameters.
This method simply takes the color that is passed to it, and assigns that to the color of the car (updates the color, as the method is called).
From the driver class, you must instantiate objects from the class.
So,
Car myCar = new Car()
Once it is instantiated, you can call the methods that belong to it.
myCar.updateColor(red);
The color between the brackets here is the actual parameter. This assumes that red is a predefined variable for a color, otherwise you can call new Color() and define your own.
I am trying to build a complete program from the partial code of a book. The difficulty is when a variable's modifier is set to private, I can't access it from the main method of my BankTest class after instantiating an object. Am confused on how to pass the Dollar Object as I can't set it to a primitive type like double or float.
Is there a way to set the Dollar object with amount = 100, so that when I run the BankTest class, I could get it to print the getAmount = 100 ? I want to maintain the Dollar object as the parameter of a method if possible ?
final class BankTest {
public static void main(String args[]) {
BankAccount ba = new BankAccount();
Dollar d = new Dollar(100);
//d.setAmount(100.00); "IF class Dollar method is PUBLIC"
//ba.deposit(d); "How to set the value of Dollar Object ??
System.out.println("Balance available: " + d.getAmount());
}
}
final class BankAccount {
private Dollar balance;
private boolean receipt;
public void deposit(Dollar amount, boolean receipt) {
balance.add(amount);
// if receipt == true, print receipt
}
public void deposit(Dollar amount) {
// validate and chain to base method
deposit(amount, true);
}
}
final class Dollar {
private double amount = 0;
public Dollar(double _amount) {
setAmount(_amount);
}
private void setAmount(double amt) { //can only be called by within Dollar class
// make sure amt is a valid currency amount
amount= amt;
}
double getAmount() {
return amount;
}
public void add(Dollar amt) {
// validate amt
amount+= amt.getAmount();
}
}
It seems Dollar was created to not be modified, but I wonder why the attribute is not final and why it can be modified by adding another Dollar object...
The idea is you have to create a new instance of Dollar every time you need a new value. Something similar happens with String and any primitive wrapper class (Integer, Float...).
As you are taking the code from a book you can decide how to deal with it: you can make the setter public or you can live with the current status and create a new object when needed.
You can already add an amount, so I think I'd modify the setter to public
Simply make setAmount public.
And also add a getter. eg getAmout() that returns the current dollar value.
Setters and getters are meant to be public, else they are pointless.
You could also pass the dollar value in the constructor.
As part of an autograder for a class I'm teaching, I would like to be able to test whether a student wrote a method whose return type was a numeric type (int, double, Integer, Double, etc.). I tried to do this as follows:
Method m = StudentClass.class.getDeclaredMethod(/* ... */);
return Number.class.isAssignableFrom(m.getReturnType());
This code will work correctly if the return type of the method is Integer or Double, but not if it's int or double. This confuses me, since it's legal to write
Number n = 137; // Assign an int to a Number
and
Number n = 1.608; // Assign a double to a Number
Why doesn't the code I've written above correctly if the method returns int or double? Aside from hardcoding tests to see if the result is int, long, char, double, etc., what can I do to test if the method returns a result of numeric type?
Thanks!
This solution does not touch the underlying cause but instead provides a workaround. It is not very elegant but considering it should never change (not unless Java somehow adds a new numeric type), I'm willing to put up with it for clarity reasons.
public class Main {
private static List<String> validTypes = new ArrayList<String>() {{
add("int");
add("Integer");
add("double");
add("Double");
add("long");
add("Long");
add("float");
add("Float");
}};
public static void main(String[] args) {
Main main = new Main();
for(Method m : main.getClass().getDeclaredMethods()){
System.out.println(m.getName() + ": " + validTypes.contains(m.getReturnType().getSimpleName()));
}
}
public static int mInt(){ return 1; }
public static Integer mInteger(){ return 1; }
public static double mDouble(){ return 1.0; }
public static Double mDoubleD(){ return 1.0; }
}
Output
main: false
mDoubleD: true
mInt: true
mInteger: true
mDouble: true
The problem you have is that int, long, double are primitives and not objects at all and do not inherit from Number. Its possible but unlikely someone could role there own version of a number class that also did not inherit from number which could make this question harder to answer but generally you would be ok yo do your number check and then also hardcode the primitives.
An alternative is to actually call the method with a value and check that the value back is numeric doing a similar thing to your cast above and checking for the exception or using http://commons.apache.org/proper/commons-lang/javadocs/api-3.1/org/apache/commons/lang3/math/NumberUtils.html isNumber on the String.valueof result. Of course its eniterly possible that someone could still write a class/method that could do the correct thing but fail any of these checks.