Hi and hope someone can help. I'm doing a short Java course and need to set up 3 classes that basically communicate between each other but I'm failing.
You'll spot from the code below that I'm trying to split the tasks of reading user's input and doing whatever maths is required into different classes but something's wrong
Any ideas? Thanks for your interest.
Here's the simple Main class:-
public class Main {
public static void main(String[] args) {
Calculator calculator = new Calculator();
calculator.start();
}
}
The Calculator class (or part of it):-
public class Calculator {
private Reader reader;
public void Calculator(Reader reader) {
this.reader = reader;
System.out.println("Calculator set up.");
}
public void start() {
while (true) {
System.out.print("command: ");
String command = reader.readString(); // It fails here:
if (command.equals("end")) {
break;
}
if (command.equals("sum")) {
sum();
} else if (command.equals("difference")) {
difference();
} else if (command.equals("product")) {
product();
}
}
And finally the Reader class:-
public class Reader {
private Scanner input;
public void Reader(Scanner input) {
this.input = input;
System.out.println("Reader set up.");
}
public String readString() {
return input.nextLine();
}
public int readInteger() {
return Integer.parseInt(input.nextLine());
}
}
You have an issue with all the constructors you are using. Constructors are special methods with no return type, so in your case, public void Calculator(Reader reader) needs to be public Calculator(Reader reader) (remove void). The same applies to the other constructors.
Once you do that, you would need to make amendments on how you are instantiating your Calculator class:
Calculator calculator = new Calculator();
Should become:
Calculator calculator = new Calculator(new Reader(new Scanner(System.in)));
provide constructor not mothod.
Calculator(Reader reader) {
this.reader = reader;
System.out.println("Calculator set up.");
}
after that you can change your main method with #subhrajyoti suggested.
apart from above suggestion ,
1> your constructors (Reader and Calculator) is returning void. But constructor cannot return any value. So, remove void keyword.
you have to import Scanner class (i.e. java.util.scanner).
Related
What's the issue here?
class UserInput {
public void name() {
System.out.println("This is a test.");
}
}
public class MyClass {
UserInput input = new UserInput();
input.name();
}
This complains:
<identifier> expected
input.name();
Put your code in a method.
Try this:
public class MyClass {
public static void main(String[] args) {
UserInput input = new UserInput();
input.name();
}
}
Then "run" the class from your IDE
You can't call methods outside a method. Code like this cannot float around in the class.
You need something like:
public class MyClass {
UserInput input = new UserInput();
public void foo() {
input.name();
}
}
or inside a constructor:
public class MyClass {
UserInput input = new UserInput();
public MyClass() {
input.name();
}
}
input.name() needs to be inside a function; classes contain declarations, not random code.
Try it like this instead, move your myclass items inside a main method:
class UserInput {
public void name() {
System.out.println("This is a test.");
}
}
public class MyClass {
public static void main( String args[] )
{
UserInput input = new UserInput();
input.name();
}
}
I saw this error with code that WAS in a method; However, it was in a try-with-resources block.
The following code is illegal:
try (testResource r = getTestResource();
System.out.println("Hello!");
resource2 = getResource2(r)) { ...
The print statement is what makes this illegal. The 2 lines before and after the print statement are part of the resource initialization section, so they are fine. But no other code can be inside of those parentheses. Read more about "try-with-resources" here: https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
What's the issue here?
class UserInput {
public void name() {
System.out.println("This is a test.");
}
}
public class MyClass {
UserInput input = new UserInput();
input.name();
}
This complains:
<identifier> expected
input.name();
Put your code in a method.
Try this:
public class MyClass {
public static void main(String[] args) {
UserInput input = new UserInput();
input.name();
}
}
Then "run" the class from your IDE
You can't call methods outside a method. Code like this cannot float around in the class.
You need something like:
public class MyClass {
UserInput input = new UserInput();
public void foo() {
input.name();
}
}
or inside a constructor:
public class MyClass {
UserInput input = new UserInput();
public MyClass() {
input.name();
}
}
input.name() needs to be inside a function; classes contain declarations, not random code.
Try it like this instead, move your myclass items inside a main method:
class UserInput {
public void name() {
System.out.println("This is a test.");
}
}
public class MyClass {
public static void main( String args[] )
{
UserInput input = new UserInput();
input.name();
}
}
I saw this error with code that WAS in a method; However, it was in a try-with-resources block.
The following code is illegal:
try (testResource r = getTestResource();
System.out.println("Hello!");
resource2 = getResource2(r)) { ...
The print statement is what makes this illegal. The 2 lines before and after the print statement are part of the resource initialization section, so they are fine. But no other code can be inside of those parentheses. Read more about "try-with-resources" here: https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
How do I ignore the sysout statement while testing the following method?
public int inputBoardSize() {
System.out.print("Enter the number of grids you want to play with:");
while (flag) {
try {
boardSize = validateBoardSize(Integer.parseInt(scan.nextLine()));
} catch (NumberFormatException e) {
System.err.println("Please enter a number");
}
}
printBoard(boardSize);
return boardSize;
}
So when I am testing this method, I get a prompt asking me to enter the number of grids. How do I solve this?
You need to mock the resource. Therefore create a wrapping interface like
public interface LineProvider {
String nextLine();
}
and implementing classes, first the class that you will use in the actual program:
public class UserInput implements LineProvider {
private Scanner mScanner;
public UserInput(Scanner scanner) {
mScanner = scanner;
}
#Override
public String nextLine() {
return mScanner.nextLine();
}
}
And then your mock that you will use for tests:
public class UserInputMock implements LineProvider {
private String mLineToReturn;
public UserInputMock(String initialLine) {
mLineToReturn = initialLine;
}
public void setLineToReturn(String lineToReturn) {
mLineToReturn = lineToReturn;
}
#Override
public String nextLine() {
return mLineToReturn;
}
}
Now let your method accept the resource as parameter:
public int inputBoardSize(LineProvider provider) {
...
boardSize = validateBoardSize(Integer.parseInt(provider.nextLine()));
...
}
And in your main program you use an UserInput like
UserInput userInput = new UserInput(scan);
...
inputBoardSize(userInput);
whereas in your test you use the mock:
UserInputMock mock = new UserInputMock("hello world");
inputBoardSize(mock); // Not valid
mock.setLineToReturn("5");
inputBoardSize(mock); // Valid
Note that there are frameworks to make stuff like that easier.
In class we learned about methods, but I'm having a bit of trouble using them.
In a package called util, I wrote a class called IO.
public class IO {
public static float getFloat(){
String str = JOptionPane.showInputDialog("Enter a real number");
return Float.parseFloat(str);
}
public static void showMessage(Scanner s){
System.out.println(s);
JOptionPane.showMessageDialog(null, s);
}
public static Scanner getInput (String prompt){
String s = JOptionPane.showInputDialog(prompt);
return new Scanner(s);
}
}
Also in package util, I have my program, called Program 4.
public class Program4 {
public static void main(String[] args) {
IO.getInput("enter 2 integers");
IO.showMessage(Scanner(s));
}
}
What I don't understand is how do I display the 2 integers entered? One is a scanner object and one is string. How do I use the method getInput to show convert the scanner into a string? Am I going to have to write a new method and use parse?
You can get user input without using Scanner. Here is example:
IO Class
public class IO {
public static float getFloat() {
String str = JOptionPane.showInputDialog("Enter a real number");
return Float.parseFloat(str);
}
public static void showMessage(String s) {
System.out.println(s);
JOptionPane.showMessageDialog(null, s);
}
public static String getInput(String prompt) {
// JOptionPane.showInputDialog() return user input String
String input = JOptionPane.showInputDialog(prompt);
return input;
}
}
Program4 Class
public class Program4 {
public static void main(String[] args) {
// IO.getInput() return stored input String
String input = IO.getInput("enter 2 integers");
IO.showMessage(input);
}
}
This was an exam question which I couldn't complete.
How do you get the following java code to print false by only
editing code within the MyClass constructor?
public class MyClass{
public MyClass(){
}
public static void main(String[] args) {
MyClass m = new MyClass();
System.out.println(m.equals(m));
}
}
You are NOT allowed to override the equals method, or change any of
the code within the main method. The code must run without the program
crashing.
According to my research, you can't set a Java object reference to null when you instantiate a class. So I'm officially stumped.
That was tough!!
public MyClass() {
System.setOut(new PrintStream(new FilterOutputStream(System.out) {
#Override
public void write(byte[] b, int off, int len) throws IOException {
if(new String(b).contains("true")) {
byte[] text = "false".getBytes();
super.write(text, 0, text.length);
}
else {
super.write(b, off, len);
}
}
}, true));
}
Or Paul Boddington's simplified version:
PrintStream p = System.out;
System.setOut(new PrintStream(p) {
#Override
public void println(boolean b) {
p.println(false);
}
});
Or AJ Neufeld's even more simple suggestion:
System.setOut(new PrintStream(System.out) {
#Override
public void println(boolean b) {
super.println(false);
}
});
Something along these lines, I would guess:
public MyClass() {
System.out.println(false);
System.exit(0);
}
EDIT: I found a puzzle very similar to yours in Java Puzzlers, except in that question the only restriction was that you could not override equals, which basically makes the solution to overload it instead and simply return false. Incidentally, my solution above was also given as an alternative answer to that puzzle.
Another solution is
public MyClass() {
new PrintStream(new ByteArrayOutputStream()).println(true);
try {
Field f = String.class.getDeclaredField("value");
f.setAccessible(true);
f.set("true", f.get("false"));
} catch (Exception e) {
}
}
The first line is needed because it is necessary for the string literal "true" to be encountered in the PrintStream class before the backing array is modified. See this question.
This is my solution
public class MyClass {
public MyClass() {
System.out.println("false");
// New class
class NewPrintStream extends PrintStream {
public NewPrintStream(OutputStream out) {
super(out);
}
#Override
public void println(boolean b) {
// Do nothing
}
}
NewPrintStream nps = new NewPrintStream(System.out);
System.setOut(nps);
}
public static void main(String[] args) {
MyClass m = new MyClass();
System.out.println(m.equals(m));
}
}
Basically, this is the variation of #fikes solution.