I am current writing a program that includes a test. When the user clicks submit it either prints out correct or incorrect and then goes to a different class. As well as doing this i want if the answer is correct to add 1 to a variable.
The thing i can't work out is how to do this in different classes since 1 or 0 will need to be added for everything question which are saved in different classes but in the same project.
Is there any reason that each question is a separate class? It seems that you could have a single Question class which hold instance variables, such as
public class Question{
private String text; //the question itself
private String[] choices; //the choices if this is a multiple-choice question
private int answer; //the index in choices that is the correct answer
//constructor, accessors, mutators
public String toString(){
String retval = this.text+"\n";
for(int x=0;x<choices.length;x++){
char c = 'a'+x; //this will give characters going alphabetically from 'a'
retval+=c+") "+choices[x]+"\n";
}
return retval;
}
}
Then you could have a Test class with the main method.
public class Test{
public static void main(String args[]){
Question[] questions = {
new Question("What is 1+1?", new String[]{"2", "3", "4"}, 0),
//other questions here
}
int total=0;
Scanner input = new Scanner(System.in);
for(Question q: questions){
System.out.println(q.toString());
int ans = input.nextLine().charAt(0)-'a';
if(q.getAnswer()==ans){
total++;
}
}
}
}
Does this sort of do what you want?
This counter does not have a context within each of the individual classes. It only has context within the code you have managing these tests you are running. So, within this manager class, you have one variable that you increment each time a test completes and you detect it to be correct.
You want a different class with a public final static class and variable.
Something like this:
public class Counter {
private static int count=0;
public static int add() {
return count++;
}
}
You may want a getter as well.
Whatever class has a reference to the questions should loop through them and sum up a total of correct questions. If your questions don't inherit from the same class create an interface named Question that has a isAnswerRight() method that you can call, or something similar.
Related
I am learning Java, so I understand this is a very simple question, but I still want to understand it.
I want to let my code automatically generate soldiers, and the number automatically increases, but I failed.
the Soldier.class:
package com.mayer;
import java.util.Random;
public class Soldier {
private int number=0;
private int ATK;
private int HP;
Random ra = new Random();
public Soldier(){
this.number++;
this.ATK = ra.nextInt(10)+90;
this.HP = ra.nextInt(20)+180;
}
public void report(){
System.out.println("number:"+this.number+"\t"+
"ATK:"+this.ATK+"\t"+
"HP:"+this.HP);
}
}
the main.class
package com.mayer;
public class Main {
public static void main(String[] args) {
Soldier[] soldiers = new Soldier[5];
int i = 0;
while(i<5){
soldiers[i] = new Soldier();
i++;
}
for(Soldier sol:soldiers){
sol.report();
}
}
}
That's what I get:
number:1 ATK:94 HP:187
number:1 ATK:94 HP:181
number:1 ATK:96 HP:193
number:1 ATK:90 HP:183
number:1 ATK:95 HP:193
So you see,each of this number is 1.
You have added number field which is instance field. It will initialize per instance. You are looking for static type variable. Please check static into java.
Instance Variables (Non-Static Fields) Technically speaking, objects
store their individual states in "non-static fields", that is, fields
declared without the static keyword. Non-static fields are also known
as instance variables because their values are unique to each instance
of a class (to each object, in other words); the currentSpeed of one
bicycle is independent from the currentSpeed of another.
Class Variables (Static Fields) A class variable is any field declared with the static modifier; this tells the compiler that there
is exactly one copy of this variable in existence, regardless of how
many times the class has been instantiated. A field defining the
number of gears for a particular kind of bicycle could be marked as
static since conceptually the same number of gears will apply to all
instances. The code static int numGears = 6; would create such a
static field. Additionally, the keyword final could be added to
indicate that the number of gears will never change.
The constructor is changed to:
public Soldier(int number){
this.number = number;
this.ATK = ra.nextInt(10)+90;
this.HP = ra.nextInt(20)+180;
}
As others have said, each Soldier instance has its own separate number field which starts with 0. You can use a static field to count the instances:
public class Soldier {
private static int counter = 0;
private int number;
// other fields left out for clarity
public Soldier(){
Soldier.counter++; // field shared among all Soldier instances
this.number = counter; // number belongs to this instance only
// ...
}
// ...
}
However, I wouldn't recommend doing it this way. When you get more advanced, you'll learn that using a static field like this can cause problems in a multi-threaded application. I would instead advise passing the number to the Soldier constructor:
public class Soldier {
private int number;
// ...
public Soldier(int number){
this.number = number;
// ...
}
// ...
}
And then:
public static void main(String[] args) {
Soldier[] soldiers = new Soldier[5];
int i = 0;
while(i<5){
soldiers[i] = new Soldier(i);
i++;
}
Soldier.class
all-uppercase field names tend to be used for constants.. basic fields use headless camel-case.. They should also be descriptive, i.e. you should look at them an it should be apparent what they represent - for example a variable "number" is not a good idea, because it's ambiguous
Random can be converted to a local variable, no need to keep it on the class level
The mechanism by which soldiers are assigned IDs should be on a higher level - it can't be managed by the soldier object itself, hence the constructor with an argument
overriding the toString method is the traditional way of transforming the object to string for debugging purposes.. also most IDEs can generate it with a press of a button so no space for human error
You will obviously need getters and setters for your variables, if you wish to read or change them from elsewhere, but I don't think that's necessary to post here.
private int soldierID;
private int attack;
private int health;
public Soldier(int id){
this.soldierID = id;
Random random = new Random();
this.attack = random.nextInt(10) + 90;
this.health = random.nextInt(20) + 180;
}
#Override
public String toString() {
return "Soldier{" +
"soldierID=" + soldierID +
", attack=" + attack +
", health=" + health +
'}';
}
Main.class
it's perfectly fine and actually preferred to use a List instead of an array, because it's more comfortable to work with
this way it's even much easier to add them dynamically and use the iterator for ID
you can "report" in the creation cycle
This even shortens the method a bit, not that it's that important here.
public static void main(String[] args){
List<Soldier> soldiers = new ArrayList<>();
for(int i=0; i<5; i++){
Soldier newSoldier = new Soldier(i);
soldiers.add(newSoldier);
System.out.println(newSoldier.toString());
}
}
This way when you define the soldier IDs it's not from within the Soldier class but rather from something that is "observing" all the soldier classes and knows which is which.
Imagine you want to create an unknown amount of instances of a class. You decide to use an ArrayList (if there is a better option I would very much appreciate if someone could explain this) You want to allow instances of the class to be created through the System Input.
import java.util.ArrayList;
import java.util.Scanner;
class MyClass {
static ArrayList<MyClass> myArrayList = new ArrayList<>();
int field1;
int field2;
int field3;
public MyClass(int field1, int field2, int field3) {
// contructor statements
}
Here is the problem, if you scan inputs, you cannot feed them into the constructor, as you need to print messages in between and then scan the input. You are forced to store the values of all the fields by assigning them to other variables as shown below, you can also set the fields at the index of the new object each time you scan them, but this seems like it would be slow and complicated code.
static void createNewInstance() {
Scanner myScanner = new Scanner(System.in);
System.out.println("Enter field 1");
int f1 = myScanner.nextInt();
System.out.println("Enter field 2");
int f2 = myScanner.nextInt();
System.out.println("Enter field 3");
int f3 = myScanner.nextInt();
myArrayList.add(new MyClass(f1, f2, f3));
}
}
So I am wondering if there is a way to pass the scanned input directly into the constructor, it seems like storing the values as variables would take a bit of computation and also, if these variables are primitive, i think they would be in stack, which stack has static memory allocation, so they are permanently there. It seems to me like on a large scale, this is not such a great solution, but I am also extremely limited in my knowledge of program performance, so I am not exactly sure. I am guessing the answer is just use that solution, any others are just too complicated to be worth using. Thank you for reading, sorry I have struggled to word this question in a concise way.
In "normal" situation you will never create objects like this - there are many many ways the application receiving objects (reading from batch, receiving HTTP requests, deserialization...) and I never saw "on production" prompting the user "now give me the value of the first field..." etc and scanning values
it seems like storing the values as variables would take a bit of computation
and that's not a problem at all - creating objects in Java is super fast, additional three primitive fields are not relevant at all when it comes to the performance
Don't overengineer this
Firstly, lets mention that Premature Optimization Is the Root of All Evil
Having mentioned that, if you still want to get your user input through the stdin, you could asks your user to provide his numbers at once.
e.g
"Provide your numbers seperated by ,"
And then, after using scanner.nextLine() you can split the line and get your numbers (and validate that all 3 numbers were given).
Builder pattern and optionally Project Lombok are your friends!
public static void main(String[] args) {
MyClass obj = createNewInstance();
}
public static MyClass createNewInstance() {
Scanner scan = new Scanner(System.in);
MyClass.MyClassBuilder builder = MyClass.builder();
builder.field1(scan.nextInt());
builder.field2(scan.nextInt());
builder.field3(scan.nextInt());
return builder.build();
}
#Builder
#RequiredArgsConstructor
public static class MyClass {
private final int field1;
private final int field2;
private final int field3;
}
Another option is to put Scanner directly to the constructor (but this is NOT GOOD from Object Design Principles)
public static void main(String[] args) {
MyClass obj = new MyClass(new Scanner(System.in));
}
public static class MyClass {
private final int field1;
private final int field2;
private final int field3;
public MyClass(Scanner scan) {
field1 = scan.nextInt();
field2 = scan.nextInt();
field3 = scan.nextInt();
}
}
General part first:
This is for my Java 1 final: I need to make an NFL playoff simulator. So, I would make a "Team" object that holds values for "Offense" and whatnot. I would need a method that holds an algorithm to calculate who wins each matchup. However, I don't know how to go about applying the method to the appropriate teams..
I was going to make another object called "Matchup" which would hold 2 "Team" objects, then comparing the 2 teams' values with the algorithm method. But, I don't think you can use objects inside another object, to my knowledge... Therefore, I've just been trying to hard-code everything in an ugly way.
Would anyone point me in the right direction of forming such a program?
Anyway, on to my immediate issue:
Here is my small bit of code thus far..
public class Final_Larrabee {
static Team pit = new Team("Steelers", "AFC", 3, 75, 70);
static Team bal = new Team("Ravens", "AFC", 6, 70, 80);
static String teamA1 = "bal";
public static void main(String[] args) {
System.out.println(+teamA1.seed);
}
}
And my other class:
package final_larrabee;
public class Team {
String name;
String conference;
int seed;
int offense;
int defense;
boolean wcWin;
boolean divWin;
boolean conWin;
boolean alive;
public Team(String n, String c, int s, int o, int d) {
name = n;
conference = c;
seed = s;
offense = o;
defense = d;
wcWin = false; // these wins will be used in the betting part
divWin = false;
conWin = false;
alive = true; // determines if team is out of playoffs or not
}
public String getName(){
return this.name;
}
public void setName(String n){
name = n;
}
public int getConference(){
return this.seed;
}
public void setConference(String c){
conference = c;
}
public int getSeed(){
return this.seed;
}
public void setSeed(int s){
seed = s;
}
public int getOffense(){
return this.offense;
}
public void setOffense(int o){
offense = o;
}
public int getDefense(){
return this.defense;
}
public void setDefense(int d){
defense = d;
}
}
I realize this won't work, because it is trying to access teanA1's seed value (which doesn't exist of course). But, what I wanted was to simply call the bal.seed value. I wanted to do it this way so that later, I can use teamA1 and teamA2 variables for the 2 teams in a given matchup. Is there a way to do it this way?
If not, perhaps ideally, it would be best to create a Team object called teamA1 which holds the values of whatever team I need at the time. It would need to change like a variable instead of make a million objects every time I need it (ideally..) I found the method 'clone' but I'm not sure this is what I want?
Any help, be it to my immediate question, or the general layout of my program, would be much appreciated. Thanks!
make team implements comparable this will give you the ability to write compareTo method and then you can put you win condition based
Just as your class Final_Larrabee holds 2 team objects in your code, your matchup class can also hold other objects.
Yes, you're on the right track with the idea of creating a matchup class which holds instances of team objects.
Inside your main class you can initialize 2 team objects. I would then create a matchup object, which gets passed the 2 team objects you have previously created and do some functionality.
Inside your team class you could implement a method, which returns a score based on the teams stats. For example it could calculate the offense * defence * seed or something like and return it that and then inside your match class, you can then implement a method such as playGame() which calls the getScore() method of each object and compares the values and then returns the winner (or prints them out for simplicity).
As regards your code, you're using the keyword static. Static is a keyword which changes a variable/object/method to a class variable/object/method. This means that every instance of the class shares this variable. I would not use it for creating the teams. An example of where to use static (a very basic example), would be if for some reason you needed to keep track of the amount of team objects you created. You could implement a static COUNT variable inside the team object and increase it by one every time the constructor is called. This could also be used for assigning IDs to the teams.
static int TEAM_COUNT = 0;
public Team()
{
this.id = ++TEAM_COUNT;
}
This would make the TEAM_COUNT be a value which shared by all instances of the class team. If you were to call
teamA.setTeamCount(0);
Then every other instance of Team would also be reset to 0.
Edit: With regards to your playoffs
public static void main(String args[])
{
Team team1 = new Team("parameters required here");
Team team2 = new Team("parameters required here");
Playoff p = new Playoff();
p.add(team1);
p.add(team2);
p.startPlayoffs();
}
If you create all of the objects inside the main class, then they are available to that method as they are local. When you call p.add(), you can add them to an array or collection, which is inside the Playoff class. Your startPlayoffs() method can then process the array of objects already stored inside the class.
I have 2 classes right now, the first class has the arraylist in it. But on the second class when I try to access the arraylist it keeps giving me the red line underneath saying that the variable doesn't exist.
Here is class one...
public class BankMain {
public static void main(String[] args) {
// TODO Auto-generated method stub
BankMain main = new BankMain();
menu();
}
public static void cardNumbers(){
ArrayList<Integer> cardNum = new ArrayList<Integer>();
Scanner cards = new Scanner(System.in);
Scanner input = new Scanner(System.in);
Scanner keyboard = new Scanner(System.in);
System.out.println("Please select a 5 digit card number");
cardNum.add(input.nextInt());
System.out.println("Thank you! You're card number is " +cardNum);
System.out.println("Type 'c' to go back to main menu.");
String value = keyboard.next();
if(value.equalsIgnoreCase("c")){
menu();
}
else if (!keyboard.equals('c')){
System.out.println("Invalid Entry!");
}
}
public static void menu(){
System.out.println("What Would you like to do today?");
System.out.println();
System.out.println("Create Account = 1");
System.out.println("Login = 2");
System.out.println("Exit = 3");
query();
}
public static void query(){
Scanner keyboard = new Scanner(System.in);
double input = keyboard.nextInt();
if (input == 2){
BankMainPart2 main2 = new BankMainPart2();
System.out.println("Please enter your 5 digit card number.");
main2.loginCard();
}
else if (input == 1){
cardNumbers();
}
else if (input == 3){
System.out.println("Thank you, have a nice day!");
System.exit(0);
}
}
}
Here is the second class...
public class BankMainPart2 {
public static void loginCard(){
if (cardNum.contains(name)) {
}
}
}
I know I haven't entered anything in the if statement yet on the second class but I'm just trying to get my array list to work on both classes.
The code looks very naive. A very simple answer to your question is
You have not declared any cardNum in BankMainPart2 as global variable or in loginCard as local variable, how do you think it will be available in the loginCard method?
ArrayList<Integer> cardNum = new ArrayList<Integer>();
is local to cardNumbers method.
How can you access it from other class?
A local variable cannot be accessed from outside the method, so first thing, make cardNum class level variable
Make the variable public if you want other classes to be able to access it directly, else make the variable private and create getter method (setter if required).
You can also send the variable when calling the method as argument
If this is class level variable, make it static and use Classname.variable.
--Edit--
As you have asked for details let me give you a quick overview of the different approaches.
A variable declared inside a method is local. as name suggest "local", no one but the method knows there is such a variable. No other method in the class knows about existence of this variable, let alone some outside class.
I say you can make it static, but static should strictly be used for class level storage, not object level. Say a list which is modified by multiple objects of the same class (I hope you know concepts of objects, else go to the basics otherwise it will not be clear). Now as per your example, I guess this is not what you want.
A public variable is generally no - no, only in few cases it will be useful (for example in android programming where performance is utmost important). Normally we will create a variable and provide getter setters. A getter or setter is used normally when we want to give access to the variable, which again does not look like what you want.
Last, the variable is private to you class, but if you want some method to do something about it, you can pass it as argument, this looks the case for you.
Step by step
take the variable out of method and add to class level, note that I removed static from method names
public class BankMain {
private ArrayList<Integer> cardNum = new ArrayList<Integer>();
// rest of code as it is
..
..
BankMain main = new BankMain();
//change
main.menu();
//no need foe static
public void cardNumbers(){
//no need here now
//ArrayList<Integer> cardNum = new ArrayList<Integer>();
Scanner cards = new Scanner(System.in);
Scanner input = new Scanner(System.in);
..
..
//public static void menu(){
public void menu(){
//send the list
//I see there are confusion at times regarding calling of static method.
//please note objectname.staticMethod() or classname.staticMethod() is one
//and same thing. Just that classname.staticMethod() is more clear
BankMainPart2.loginCard(cardNum);
}
and
public class BankMainPart2 {
public static void loginCard(ArrayList<Integer> cardNum){
if (cardNum.contains(name)) {
}
}
}
Your method, BankMainPart2.loginCard has not context of "cardNum", it doesn't know what it is (type or value).
In order for the method to be able to act on the array list, you must pass a reference to it, something like...
public class BankMainPart2 {
public static void loginCard(ArrayList<Integer> cardNum){
if (cardNum.contains(name)) {
}
}
}
make the cardnum arraylist as an instance variable in BankMain class and extend BankMain in BankMainClass2 and using reference of BankMain you would be able to access cardNum like this
Class BankMain {
public ArrayList<String> cardNum = new ArrayList<String>();
}
Class BankMain2 extends BankMain {
public void method() {
BankMain2 main = new BankMain2();
sysout(main.cardNum.size());
}
}
but the above scenario would only work when cardNum ArrayList in BankMain class is either marked public,protected or default(Nomodifier). it wouldnt work if its marked as private and other non access modifier such as static and final
You can try any one of these
1.Declare the Arraylist as public then import the first class and use the cardNum in the second class
2.Make the cardNum a static var and use it directly in second class as BankMain.cardNum
3.Pass the Arraylist as argument to the second class.
The key problem is in the the way you are trying to create your classes. Your current problem can be solved by answer given by #MadProgrammer. But you should definitly have a look into the Object Oriented Programming Concepts. This section on How to identify and design a Class? should give you some clear pointers.
Say I wanted to make a class to hold a set of integers that would be accessed from multiple other classes and instances. I don't want them reverting to the value they had when the code was compiled. Does that mean they have to be static, in order to keep them from going back their original value? For example
The original stats holding class here:
public class Stats() {
public static int numOne = 0;
public static int numTwo = 5;
public static int numThree = 3
//etc...
}
It is called on in two places. Here:
public class exampleClass() {
private Stats stats = new Stats();
stats.numOne += 5;
//More variable changes.
}
Also here:
public class exampleClassTwo() {
private Stats stats = new Stats();
stats.numOne -= 3;
//More variable changes.
}
Will these calls reset the variables to their original class value if the variables are not static? If so, does that mean they should always be static?
No, the variables will maintain state without the static modifier
No. You would use static key word for using those values without initializating them.
public class Stats() {
public static int numOne = 0;
public static int numTwo = 5;
public static int numThree = 3
//etc...
}
public class exampleClass() {
int a = 0;
a += Stats.numThree;
System.out.println(a);
}
>>> 3;
No need for static attributes in your case indeed, each class instance will contain a private copy of attributes initialized at instance creation time, and records all subsequent modifications until object is deleted (in java it means no longer referenced).
Main usage for static is either to store constants or global state (e.g. a singleton instance).
Doing,
private Stats stats = new Stats();
stats.numOne += 5;
Kind of defeats the purpose of having numOne as static.
The static field numOne should be accessed in a static way i.e as follows: Stats.numOne
static variables are Class variables and are used when we want to maintain a value across instances of the class. So modifying the value of numOne across various functions will keep on changing the value of class variable numOne. Run the following code to see the effect of having a class variable in a class:
public class StaticVarDemo {
public static int staticCount =0 ;
public StaticVarDemo(){
staticCount++;
}
public static void main(String[] args) {
new StaticVarDemo();
StaticVarDemo.staticCount +=5;
System.out.println("staticCount : " + StaticVarDemo.staticCount);
new StaticVarDemo();
new StaticVarDemo();
System.out.println("staticCount : "+staticCount);
}
}
It will give the output:
staticCount : 6
staticCount : 8
Yes, when you instantiate an object, variables will be initialized to the class values when they are not static.
When a variable has the static keyword, that variable value persists over all instances: the two places you called it each create an object, both objects have the same values for their static variables (even if they are changed).
Variables without the static keyword are unique to the instance: changing it on one object doesn't affect its value on the other.
See here for more info:
What does the 'static' keyword do in a class?
It seems after some research a singleton did the job. Creating one singular instance but calling on it more then once.
See Here:
http://www.tutorialspoint.com/java/java_using_singleton.htm