On Formatting
You can format your output using System.out.printf
, or String.format()
For example, if you wanted your division test result to only include 2 digits after the decimal you could instead call System.out.printf("Division: %.2f%n", calc.divide());
The % is a special character; when the printf method reaches it it replaces that location with the specified formatted version of the proceeding arguments (You can have several in one line as long as they are in order). The '.2' that proceeds is what enforces only 2 digits after the decimal. The %n that immediately follows is so you can still have a new line after calling printf. You can read more about formatting and find some additional examples here.
On Exception Handling
I'll also echo the previous answer in saying that handling edge cases would do you some good, this could be done with a simple conditional within the method to ensure the divisor is not 0, which would otherwise cause an error or report NaN/infinity when it is undefined.
You could throw an exception if the divisor is 0 within the divide method itself, like so:
public double divide() {
if (num2 == 0) {
throw new ArithmeticException("Dividing by 0 is undefined");
}
return num1 / num2;
}
The message could be a simple "Cannot divide by 0." Which, if you catch it, would allow a 0 divisor to exist, and you don't have to constrict the possible num2 values and calculations possible.
On Java Convention & Readability
- variables and methods are camelCase
- Class and interface name are PascalCase
- CONSTANTS are UNDERSCORE_CAPITALIZED
Also, try to have a line break between your methods, it'll aid in readability once method body increases. Though I personally omit this when the methods are closely linked, like getters and setters for the same value, as @Rhuarc13 suggest you have.
Although I disagree with adding anything not explicitly necessary(any user trying to pass a no arg constructor would encounter a compilation error) since this is an exercise on encapsulation I think a getter has some merit. Setters don't make sense in this case given your variables' final state, but if you instantiated several of these Calculate objects with different values it would be helpful to have a method to keep track of them without providing users with access to the variable itself, which would break encapsulation*.
- Access to the variable directly is arguably inconsequential since it's final, but the point of encapsulation is that the external users should not concern themselves with the fields or implementation.
If you go in your calculate and added methods like so:
public double getNum1() {
return this.num1;
}
public double getNum2() {
return this.num2; // this keyword refers to that particular object
}
Then when you're interested in what value is actually contained within the object for example in your test case you could call
System.out.println("Number 1: " + calc.getNum1());
System.out.println("Number 2: " + calc.getNum2());
Alternative Implementation
If you were interested in setters as well, if you had private instead of final values you could use something like this:
public class Calculator {
private double num1;
private double num2;
public Calculator setNum1(double num1) {
this.num1 = num1;
return this;
}
public Calculator setNum2(double num2) {
this.num2 = num2;
return this; // return the current state of Calculator to allow for chaining
}
public double divide() {
return num1 / num2;
}
public double add() {
return num1 + num2;
}
public static void main(String[] args) {
// You can chain call them
Calculator example = new Calculator().setNum1(3).setNum2(5);
System.out.println(example.add());
// Or use it separately.
example.setNum1(45);
System.out.println(example.divide());
}
}
On User Input + Further input validation
Your revision seems concerned with user input, if you actually want to get and use input, a simple way to do that is to make use of Scanner.
Make sure to retrieve the resource at the top: import java.util.Scanner
and then declare an instance: Scanner input = new Scanner(System.in)
The nice thing about that is you could ensure a non-0 divisor with a while loop.
for instance if in your main method you did:
System.out.print("Enter second value: ");
double val2 = input.nextDouble();
You could proceed with this:
while (val2 == 0) {
System.out.print(
"Second value cannot be 0" +
"\nEnter a non-0 value: ");
val2 = input.nextDouble();
}
and that would make sure that your user provided a non 0 divisor.