views:

53

answers:

1

Just started learning Java a week or so ago. I have made a little Java program that calculates the amount of reviews, and the average review rating that something has. For instance, on the app store, you would enter in 1 star, 2 star, 3 star, 4 star, and 5 star reviews and the program would calculate the average review score. Anyway, maybe it would just be easier to show you. What I want to do is have the keyboard input section in a different class. But when I tried to do this, the compiler said "cannot find symbol" I know there is no global variables in Java, but surely there is a way to pass the user-input variable into a different class(?). I have tried the "extends" keyword to make my keyboard class a subclass, but that didn't work either. I essentially need to access the firStar, secStar, thrSstar, fouStar, and fivStar variables in the reviewHandler class, when those variables are originally defined in the keyboardInput class.

reviewHandler class:

public class reviewHandler {

public void reviews() {

keyboardInput keyboard = new keyboardInput();
keyboard.fiveStar();

int oneStar = firStar;
int twoStar = secStar;
int threeStar = thrStar;
int fourStar = fouStar;
int fiveStar = fivStar;

int starOne = oneStar * 1;
int starTwo = twoStar * 2;
int starThree = threeStar * 3;
int starFour = fourStar * 4;
int starFive = fiveStar * 5;

int reviewCount = oneStar + twoStar + threeStar + fourStar + fiveStar;

double reviewStarCount = starOne + starTwo + starThree + starFour + starFive;

double reviewAverage = reviewStarCount / reviewCount; 

reviewAverage = reviewAverage * 100;
reviewAverage = Math.round(reviewAverage);
reviewAverage = reviewAverage / 100;

System.out.println("Total reviews: " + reviewCount);
System.out.println("Average review score: " + reviewAverage);
}
}

keyboardInput class:

import java.util.Scanner; 

public class keyboardInput extends reviewHandler {

public void fiveStar() {

Scanner stars = new Scanner(System.in);
int firStar, secStar, thrStar, fouStar, fivStar; 
System.out.println("Number of 1 star reviews: ");
firstar = stars.nextInt();
System.out.println("Number of 2 star reviews: ");
secstar = stars.nextInt();
System.out.println("Number of 3 star reviews: ");
thrstar = stars.nextInt();
System.out.println("Number of 4 star reviews: ");
foustar = stars.nextInt();
System.out.println("Number of 5 star reviews: ");
fivstar = stars.nextInt();

}
}

reviewLauncher class:

public class reviewLauncher {

public static void main (String[] args) {
reviewHandler start = new reviewHandler();
start.reviews();

}
}

EDIT: If I move the firStar, secStar, thrSstar, fouStar, and fivStar variables out of the method, transforming them into instance variables, the program compiles and runs, but the program will return a 0 when I try to use it.

A: 

Okay, with the revised question I think I've got a better idea of what you want to do.

What this program is screaming for is a helper class to hold the aggregate review information. Something like this:

public class ReviewInfo {
    public int numFiveStars = 0;
    public int numFourStars = 0;
    public int numThreeStars = 0;
    public int numTwoStars = 0;
    public int numOneStars = 0;
}

That gives you one nice neat bundle where you can hold all the data you're reading from the keyboard input.

Next, update your keyboardInput class so that the fiveStar() method stores all your data in a ReviewInfo object, and returns that object back to the calling code:

import java.util.Scanner; 

public class keyboardInput extends reviewHandler {

    public ReviewInfo fiveStar() {
        Scanner stars = new Scanner(System.in);
        ReviewInfo info = new ReviewInfo();
        System.out.println("Number of 1 star reviews: ");
        info.numOneStars = stars.nextInt();
        System.out.println("Number of 2 star reviews: ");
        info.numTwoStars = stars.nextInt();
        System.out.println("Number of 3 star reviews: ");
        info.numThreeStars = stars.nextInt();
        System.out.println("Number of 4 star reviews: ");
        info.numFourStars = stars.nextInt();
        System.out.println("Number of 5 star reviews: ");
        info.numFiveStars = stars.nextInt();

        return info;
    }
}

And now you can simplify the reveiwHandler.reviews() method so that it uses the ReviewInfo helper class:

...
keyboardInput keyboard = new keyboardInput();
ReviewInfo info = keyboard.fiveStar();
int oneStar = info.numOneStars;
int twoStar = info.numTwoStars;
int threeStar = info.numThreeStars;
int fourStar = info.numFourStars;
int fiveStar = info.numFiveStars;
...

And from there you're good to go, I think.

In your question, you ask about how to share variables between classes. There are ways to do this (static variables, inner classes, and various other techniques), but it's almost always a bad idea. If you're taking a class or reading a book, I'm sure you've heard/read the term "encapsulation". Global variables or variables that are shared between classes break encapsulation, and if you rely on them you run the risk of creating code that's very difficult to work on or use. Globals don't typically cause trouble on small projects like this one, but for anything bigger, they'll quickly burn you.

I hope this answers your question. Good luck!

-Chris

DeathB4Decaf
Hey, Chris, thanks for replying. I have been reading over my original post, and realized that it really didn't make sense as to what I am needing help with. If you could, I would appreciate if you could read over my original post again, as it is edited now to better describe what I am asking.
Nicholas
Ah, okay. I think I understand what you're asking now. If I have it right, you want to change the above code (which works) so that keyboardInput.fiveStar() sets the member variables within reviewHandler. This is possible using inner classes, but not the way I'd advise. I'll post a new answer.
DeathB4Decaf
Thank you so much for your reply. It makes a lot of sense. I do have another question though. With a project like this, how can you go about doing encapsulation? With a huge project, do people just have everything in these HUGE classes? How can I encapsulate?
Nicholas
That is a deep question. With experience, you'll learn when strict encapsulation is worth the trouble. HOWEVER, since you're just starting out, it's worth building good habits and then learning when you can let them slide, rather than the other way around. For more info, start with whatever you can find on "Model View Controller" architecture, and on "Design Patterns" in general. If you really want to dive in, check out "Design Patterns: Elements of Reusable Object-Oriented Software". And download and play with some open-source software so you can see how more experienced coders do it.
DeathB4Decaf