Java - Understanding classes, methods and parameters - java

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.

Related

What is the difference between void and return even though I can get same output on both?

i made a small program for summing two numbers
if i used a void type method it will be like this
import java.util.Scanner;
public class NewClass {
public static void main(String[] args) {
Scanner input = new Scanner (System.in);
System.out.println("enter x");
int x = input.nextInt();
System.out.println("enter y");
int y = input.nextInt();
getSum(x,y);
}
public static void getSum(int x, int y)
{
int sum = x + y;
System.out.println("sum = " + sum);
} }
here if i used a method that returns a value i will get same output!
import java.util.Scanner;
public class NewClass {
public static void main(String[] args)
{
Scanner input = new Scanner (System.in);
System.out.println("enter x");
int x = input.nextInt();
System.out.println("enter y");
int y = input.nextInt();
int r = getSum(x,y);
System.out.println("sum = " + r);
}
public static int getSum(int x, int y)
{
int sum = x + y;
return sum;
}}
so i'm confused what is the benefit of returning a value if i can finish my program with a void type method?
The point is not to get the result but the way we get the result
consider
public static void getSum(int x, int y)
{
int sum = x + y;
System.out.println("sum = " + sum);
}
will print the output to the screen after calculation
but when we use return
as you have done it later
public static int getSum(int x, int y)
{
int sum = x + y;
return sum;
}
this function will respond back the sum. that sum can be stored in a variable
can be used afterwards
like in recursion
In small programs, you won't get the difference but while writing the big programs you have to make several functions which are being called several times and you may need the output of one function into other.
In that case, you will require return so that the output of one function can be used into other.
Hope this helps!!
I think the answer is that, if you're calling getSum() method with a return type in any other class.. you would get a returned value which can be used for further processing. .
Where as in void that's not possible... Hope this helps... Reply if any doubts..
I can understand why you have this question.
First of all, you should know that in real development, we do not use console logs.
System.out.Println();
This is used only for debugging and that too in very rare cases.
The whole point of a function is to take some input and convert to something else.
So,
public static int getSum(int x, int y) {
return x+y;
}
public static void main(String[] args) {
System.out.Println(getSum(5,10));
}
This is the better solution.
Best Regards,
Rakesh
When you use the keyword void it means that method doesn't return anything at all. If you declare a return type different to void at the method statement instead, that method must return obligatorily a valid value to the declared return type using the keyword return followed by a variable/value to send back to the class that called the method.
Defining methods here you have the java documentation for a method declaration
Answering your question, in small programs that work with primitive values it doesn't really matter but in complex program when you usually need to return specifics object types, i.e an ArrayList or actually an instance of a class you created you can't simply put it into a System.out.println and send it to the console, mostly you'll want to get something from a method and that something usually can be a more complex object than an integer or a string, the way to get that something is through the return type defined by the method's statement.
A common use of return types is when your method is static and it can't interact with the non-static instance variables of the class, this type of static methods usually get values from their arguments, do a certain kind of progress and then return a result that the method's caller can use.
Returning a value enables you to use that value in whichever way you want, including printing it or assigning it to variable for further processing. If on the other hand you print the value in the method and not return anything, i.e. making the method of type void, then that's all you can do with that method.

java extending or overriding switch cases

I'm in a java course so I'm trying to be a little vague with the code so I can learn but not cheat. The assignment is to take last week's program and extend functionality. Basically, I wrote a program where I'm using switch with two cases (not sure that's the best choice, but it's what I did), and I want to add more user options. So it currently allows input 'w', 'x', but I want to add 'y' and 'z' as options by extending class A with class B.
There is a default case in the class A that basically outputs "only enter 'w' and 'x'." The problem, is even with the new B class which extends it, it prevents anything but 'w' and 'x'.
I know I need the B class to override that so it allows w, x, y, and z, and then the default triggers when anything but those four options are entered. Either way, help please!
Below is class A (I got rid of some of the code for my question, but all the variables, user input and scanner work. It's the cases I'm having issues with):
import java.util.Scanner;
public class A {
public A()
{
// define and implement variables
// call scanner into existance to read inputs from the user
// Ask for user input (abbreviated section) and store in variables
oper = myManager.next(".").charAt(0);
switch(oper)
{
// case w call to firstMethod method
case 'w':
DoSomething = firstMethod(num1,num2);
System.out.println(" The result is "+FirstAns);
break;
// case w call to secondMethod method
case 'x':
DoSomethingElse = secondMethod(num1,num2);
System.out.println(" The result is "+SecondAns);
break;
default:
System.out.println(" Please Enter 'w' or 'x' only.");
}
/* note, this portion I got rid of some work, it's normally
math related but modified here just to return characters for
this post since I think it's irrelevant to my question (and I
don't want to cheat) */
static char firstMethod(char a)
{
return a;
}
static char secondMethod(char a)
{
return a;
}
}
}
And below is class B which extends A, and I'm not able to convince to allow more cases. Note, after compilation, I'm executing B, but it's still only allowing the cases from A.
import java.util.Scanner;
public class B extends A {
public B()
{
// define and implement variables
// call scanner into existance to read inputs from the user
// Ask for user input (abbreviated section) and store in variables
oper = myManager.next(".").charAt(0);
switch(oper)
{
// case w call to firstMethod method
case 'w':
DoSomething = firstMethod(num1,num2);
System.out.println(" The result is "+FirstAns);
break;
// case w call to secondMethod method
case 'x':
DoSomethingElse = secondMethod(num1,num2);
System.out.println(" The result is "+SecondAns);
break;
case 'y':
DoSomethingMore = thirdMethod(num1,num2);
System.out.println(" The result is "+ThirdAns);
break;
// case w call to firstMethod method
case 'z':
DoSomethingLast = fourthMethod(num1,num2);
System.out.println(" The result is "+FourthAns);
break;
default:
System.out.println(" Please Enter 'w', 'x', 'y', or 'z' only.");
}
}
// again, simplified this portion
static char thirdMethod(char a)
{
return a;
}
static char fourthMethod(char a)
{
return a;
}
public static void main(String[] args) {
B b = new B();
}
}
I then update the test program to import class B (instead of the old program which imported A since B is supposed to extend A). But it still only shows cases from A. I know it's the order of operations on how the program loads the cases, just not sure how to fix it.
The default constructor of a superclass is always called first by the default constructor of the subclass.
In your example, the class A constructor is called when creating class B with the default constructor.
A solution is to move your logic into a method with the same signature in both classes and call that method in the constructor of the superclass.
Something like this:
class A {
public A() {
logic();
}
private void logic() {
// Your switch of A
}
}
class B extends A {
public B() {
super();
}
private void logic() {
// Your switch of B
}
}
Dynamic Binding is the OO-principle behind this solution.

Using 2 classes for a Comission Calculator in Java

I am doing an assignment for a beginning Java class. We have to write a commission calculator and use two classes in it. I am stuck on how to use variables from one class in a second class. The methods that i have found so far are not working for me. Any advice would be greatly helpful. Below is the code i have so far.
package calc;
/**
*
* #author Ethan
*/
import java.util.Scanner;
public class Calc {
public static void main(String[] args) {
Scanner calcu = new Scanner(System.in); //Creats the scanner used for Input
//Sets all of the variables to be used
double sal; //salary
double com1; //Comission percentage
double com2; // Find the ammount of comisssion from yearly sales
double comp; //Yearly Sales
double frac; //Decimal Comission form
double total; // Total of Compensation of Yearly salary + Comission
System.out.println("Enter the annual Salary here: ");
sal = calcu.nextDouble();
System.out.println("Enter the total Sales here: ");
comp = calcu.nextDouble();
Rate();
frac = com1/100; //converts the Sales Comission to a decimal
com2 = frac * comp; // Find the total Comission based on the
total = sal + com2; //find the total compensation
System.out.print("Your total compensation is " + total);
}
private static void Rate(){
// Rate of commission is determined below.
if (comp < 10000)
com1 = 20; //20% commission rate
else if (comp < 30000)
com1 = 22; // 22% commission rate
else if (comp < 50000)
com1 = 23; // 23% commission rate
else if (comp < 100000)
com1 = 24; // 24% commission rate
else
com1 = 25; // 25% commission rate
}
}
The problem i have is the i can't pull the rates so they can be used in the calculations.
A few major issues on your code. Your code is encapsulated in the Calc class, but no constructor is ever called. (eg. new Calc()). Rate() is a method in Calc, so it would be called by Calc.Rate(). Check out a few more examples of how to construct a java class, and you will understand encapsulation of your variables.
You only have posted one class so far. Where is the second? You will need to make sure both classes are in separate files as well.
public class Class1(){
//Class variables
public int myPublicInt; //public variables are accessable to any class that calls it
private int myPrivateInt; //private variables can not be modified outside of the class
//Class constructor, this is used to create objects of a class
public Class1(){
myPublicInt = 0;
myPrivateInt = 1;
}
//Now we have setter and getter methods to handle private variables
public void setMyPrivateInt(int newValue){
myPrivateInt = newValue;
}
public void getMyPrivateInt(){
return myPrivateInt;
}
//lastly this is a private method, only Class1 objects can call this method
//internally, so we can call it in our constructor but not from Class2
private void somePrivateMethod(){
//does something
}
}
So Now you will have some first class, it has some data and some methods and a constructor. Making variables public is not a good idea for the security of your code, you will want to make your second program create an object of the first one to access its variables and method calls. See the below program.
public class Class2{
//Class Variables, declares an object of the first class
private Class1 myClassObject;
//Constructor for this class, instantiates the first class object
public Class2(){
myClassObject = new Class1();
}
//Main method and runtime of our program
public static void main(String args[]){
Class2 thisClass = new Class2();
thisClass.printMyPrivateIntFromClass1();
}
//Method from this class, Class2
public void printMyPrivateIntFromClass1(){
System.out.println(myClassObject.getMyPrivateInt());
}
}
So in the second class we make an object of the first one, this way we can manipulate and use that object, its data and its methods. Notice that I used constructors to make objects of each class. When you call that object you can also call its public methods and variables. Again I would not recommend making variables public because then they are too easy to manipulate. If you have public methods that lead to your variables you can use those as a safer way to change or access the data stored in them. Hope this helps explain using a class inside another.
A couple of other notes, work on indentation, you should use the same indentation for code nested on the same level, and anything nested underneath something else by use of {} should be indented in once more so that code is more readable for you and others.

Error With Big Decimal in Java

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

non-Static method toString cannot be referenced from a static context

I'm trying to create a program that reads user input and stores it and then calculates the area of a polygon. When I try and compile it it gives me one error which is the one about .toString being non static.
import java.util.Scanner;
class regularpoTest {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
boolean finished = false;
double s;
double n;
double area;
//starts loop to record data
do {
s =0;
n =0;
System.out.println("Enter the side length, or anything else to quit: ");
s = in.nextDouble();
in.nextLine();
if (in.hasNextDouble()) {
System.out.println("Enter number of sides");
n = in.nextDouble();
area = (s*s*n)/(4*Math.tan(Math.PI/n));
} else {
finished = true;
}
} while(!finished);
//This prints out the student details
System.out.println(regularpo.toString());
}
}
public class regularpo {
private double side;
private double numberOf;
private double area;
public regularpo(double side, double numberOf){
side = 0;
numberOf = 0;
area = 0;
}
public double getSide(){
return side;
}
public double getNumberOf(){
return numberOf;
}
public String toString(){
return ("area = " + area+ " side length "+side+ " number of sides "+numberOf);
}
}
You are trying to call a method of a class, when that method has been defined for (and only makes sense as) a method of an instance of that class. Maybe you mean to make an object of that class, and call its toString method, although I can't be sure from your code.
You can not access non-static methods by using classname.nonStaticMethodName. You need to instantiate your object using the new keyword. Basically, you create an instance of your object by regularpo r = new regularpo(2.0, 2.0). After that you can invoke r.toString();
Check out this SO-question for more info.
And this Oracle-tutorial explains class members well.
Suggestions:
1) Eliminate "regularpoTest". Just move "main()" into "regularpo".
2) Capitalize "RegularPo" (by convention, class names should start with a capital letter).
3) Make the RegularPo constructor actually save the initial values (not just set them to zero).
... and, most important ...
4) Your main should call RegularPo regularPo = new RegularPo (...).
Then reference object instance "regularPo".
Try to make a object of class regularpo and call toString over that object
regularpo obj=new regularpo();
obj.toString();
Also as per conventions a class name must start with Upper case,so name your class asRegularpo
toString() is a non static method in regularpro class , and we know that the non static belongs to an object so we need to create and object of same class and call it.
toString() is belongs to Object class so its non static method.
regularpo obj=new regularpo();
obj.toString();

Categories