The BAD and AVOID WHILE LEARNING solution: Move age
and math
local variables as static
fields in the class.
The class will look like this:
public class TestScanner {
static int age;
static int math;
//rest of your class...
//in method grabInput
static void grabInput() {
//comment the variables
//int age, math;
}
}
The code above will work due to the usage of static
fields. First understand what static
means and be careful when using it.
You should ask yourself the following questions:
- Should I have a method to display the fields of
TestScanner
inside the same class?
- Should I create a new instance of
TestScanner
just to display the values of another instance of TestScanner
?
In case you answer yes to both questions, then you can create a method that receives an instance of TestScanner
and prints its contents. This is how your class will look like:
public class TestScanner {
//Note: they're not static anymore (yay!)
int age;
int math;
public static void main (String args[]) {
TestScanner disInput = new TestScanner();
TestScanner gInput = new TestScanner();
gInput.grabInput();
//note that now we need to pass the instance of TestScanner
//in order to print its contents
disInput.displayInput(gInput);
}
//method for display purposes
void displayInput(TestScanner testScanner) {
System.out.println("Scanner Input here: ");
System.out.println("What is my age: ");
System.out.println(testScanner.age);
System.out.println("What is 2 +2: ");
System.out.println(testScanner.math);
}
void grabInput() {
Scanner stdin = new Scanner(System.in);
System.out.println("What is my age: ");
this.age = stdin.nextInt();
System.out.println("What is 2 +2: ");
this.math = stdin.nextInt();
}
}
Now ask yourself: do I need all this? Is this a good design? Can I perform changes easily or will it take more time and effort to, for example, add a new variable, fill it and display it?
The main problem here is called cohesion. This is, the degree of functionalities within a class. As you can see, TestScanner
itself has many responsibilities:
- Store
age
and math
- Read it from user input
- Display the data to the user
A better approach will be to separate these functionalities in two classes:
Person
(or another name) that will store the data from user input. Based on the names of age
and math
fields, I thought a proper name of the class could be Person
. This class will be in charge to store the data and provide it for different usage e.g. store user input and then use it for display purposes.
- A
TestScanner
class where you will test the usage of Scanner
to read the data from user input and display data to user.
The design will look like this:
class Person {
private int age;
private int math;
public Person(int age, int math) {
this.age = age;
this.math = math;
}
public int getAge() {
return this.age;
}
public int getMath() {
return this.math;
}
//setters avoided for this case
}
class TestScanner {
Scanner scanner;
public TestScanner(Scanner scanner) {
this.scanner = scanner;
}
public Person grabInput() {
System.out.println("What is my age: ");
int age = stdin.nextInt();
System.out.println("What is 2 +2: ");
int math = stdin.nextInt();
return new Person(age, math);
}
public void displayInput(Person person) {
System.out.print("My age: ");
System.out.println(person.getAge());
System.out.print("My value of 2 +2: ");
System.out.println(person.getMath());
}
public static void main(String[] args) {
TestScanner testScanner = new TestScanner(new Scanner(System.in));
Person person = testScanner.grabInput();
testScanner.displayInput(person);
}
}
Note: Links provided in questions are not for decoration purposes.