The question is:
Write the definition of a class Counter containing:
An instance variable named counter
of type int .
An instance variable named limit of type int .
A static int variable named nCounters which is initialized to 0 .
A constructor taking two int parameters that assigns the first one to counter and
the second one to limit . It also adds one to the static variable nCounters .
A method named increment . It does not take parameters or return a value ; if the
instance variable counter is less than limit , increment just adds one to the
instance variable counter .
A method named decrement that also doesn't take parameters or return a value ; if
counter is greater than zero, it just subtracts one from the counter .
A method named getValue that returns the value of the instance variable counter .
A static method named getNCounters that returns the value of the static variable
nCounters .
My Dilemma
The code works fine but I want to know the following:
Why is the first static private and the second one public?
My code:
public class Counter
{
private int counter;
private int limit;
private static int nCounters = 0;
public Counter (int x, int y)
{
counter = x;
limit = y;
nCounters++;
}
public void increment ()
{
if( counter < limit)
{
counter++;
}
}
public void decrement ()
{
if(counter > 0)
{
counter--;
}
}
public int getValue ()
{
return counter;
}
public static int getNCounters ()
{
return nCounters;
}
}
nCounters is a variable that you use to count the numbers of times the Class constructor has been called. It's static because is not a instance variable but a class variable (its value is shared by all the instances of that class).
nCounter is privated for encapsulate it. It can only be accessed outside the class by a read only method named getNCounters. Otherwise, I could access the value of nCounter and change it directly causing the value of classes created not reliable anymore.
You can read more about encapsulation and static methods and variables to understanding better your code.
The first static variable nCounters is private, because you want to control it in your class - you do not want any code outside of Counter to modify it. But you want to make it possible to read its value outside of Counter, thus the getNCounters() method is public.
Related
I am having a few minor issues with my class methods which I am to increment sequentially. Basically my class compiles, there is a test class and when I run the tester to get the test results I do not get the desired output I am looking for and it is followed by an error message which I will provide below.
My question is when I create an object it starts off with the the prefix + counter but does not increment it right away, I want it to be so that it increments the first object created to 1001 right away and so on and so forth. These error messages are confusing me on how the expected value is something totally different from my desired output.
I have the prefix set and a counter which starts at 1000.
public static final String TICKET_PREFIX = "VAN";
public static int counter = 1000;
public ParkingTicket(){
ticketNumber = generateTicketNumber();
}
}
private String generateTicketNumber(){
ticketNumber = TICKET_PREFIX + counter++;
return ticketNumber;
}
Here is the code from the test class code block where the error is caught
#Test
public void testConstructorTicketNumberSEquential() {
ParkingTicket.resetCounter();
ParkingTicket ticket = new ParkingTicket("Adam White","VAN5225", "1A2B3C",20 );
ParkingTicket ticket2 = new ParkingTicket("Adam White","VAN5225", "1A2B3C",20 );
ParkingTicket ticket3 = new ParkingTicket("Adam White","VAN5225", "1A2B3C",20 );
assertEquals("VAN1001",ticket.getTicketNumber());
assertEquals("VAN1003", ticket3.getTicketNumber());
and this is the error message from the tester
testConstructorTicketNumberSEquential
---
org.junit.ComparisonFailure: expected:<VAN100[1]> but was:<VAN100[7]>
at org.junit.Assert.assertEquals(Assert.java:115)
at org.junit.Assert.assertEquals(Assert.java:144)
at ParkingTicketTest.testConstructorTicketNumberSEquential(ParkingTicketTest.java:238)
Also I have a method to reset the counter. I tried just returning the counter value but I am still getting an error
public static int resetCounter(){
int reset = counter;
return reset;
}
test for the reset counter
#Test
public void testResetCounter() {
ParkingTicket.resetCounter();
assertEquals(1000,ParkingTicket.counter);
}
test run error message
testResetCounter
---
java.lang.AssertionError: expected:<1000> but was:<1005>
at org.junit.Assert.fail(Assert.java:88)
at org.junit.Assert.failNotEquals(Assert.java:743)
at org.junit.Assert.assertEquals(Assert.java:118)
at org.junit.Assert.assertEquals(Assert.java:555)
at org.junit.Assert.assertEquals(Assert.java:542)
at ParkingTicketTest.testResetCounter(ParkingTicketTest.java:264)
You currently never set the counter back to the initial value inside of resetCounter(), and you never use the return value.
In my opinion, the resetCounter() should be a void method, and simply set counter back to an initial value which is contained in a constant.
I named this constant INITIAL_COUNTER:
public static final String TICKET_PREFIX = "VAN";
public static final int INITIAL_COUNT = 1000;
public static int counter = INITIAL_COUNT;
public static void resetCounter() {
counter = INITIAL_COUNT;
}
public static void main(String[] args) {
counter++;
counter++;
System.out.println(counter);
ParkingTicket.resetCounter();
System.out.println(counter);
}
Output:
1002
1000
Here from the example main I made you can see resetCounter properly resets counter back to 1000. Simply change the value of INTIAL_COUNT to change your default count value.
On another note, you wrote you expect VAN1001 to be the ticket value of your first new ParkingTicket("Adam White","VAN5225", "1A2B3C",20 ) when you should actually expect it to be VAN1000.
This is due to using a post-increment on count instead of a pre-increment on the line below:
ticketNumber = TICKET_PREFIX + counter++;
If you want the first ticket to start at 1001 instead, change count++ to ++count, which will increment count by 1 before assigning the ticketNumber value.
private int superCount = 0;
public void calculator(JFXButton buttonName,int price,String name,int count){
float percentage = Float.parseFloat(percentageButton.textProperty().get())/100;
totalPrice += price*percentage;
count++;
status.setText(name+" has been added");
String totalPriceString = String.format("%,.0f", totalPrice);
priceLabel.setText("£"+totalPriceString);
buttonName.setText(name+" : "+count);
}
public void addSuper(ActionEvent actionEvent) {
calculator(superButton,superPrice,"Super",superCount);
}
So I'm passing superCount into calculator. Then I'm incrementing count by 1. However, since that count is actually superCount (at least I thought it was) it's not actually changing superCount.
What am I doing wrong?
Worth pointing out that you don't need to pass it in if you've already declared supercount outside of these methods - you can just increment supercount from within calculator(). If they are in different classes:
Java is pass by value and not pass by reference. So if you pass a value into a method, you're not changing the original value, only the new value that you've passed in.
count only exists inside your calculator method. You can't change the value of supercount without returning a value from calculator.
// If you change calculator to return an it
public int calculator(...) {
return count;
}
Now you could do:
supercount = calculator(superButton,superPrice,"Super",superCount);
I want to modify a non-static variable from inside my static main function and then return that modified value for use elsewhere. Here is the code:
package servletPackage;
public class Blah {
private int count = 5;
public static void main(String[] args) {
Blah blah = new Blah();
blah.count = 10;
}
// return Count
public int getCount()
{
return count;
}
}
However, when I access this count from a different file, I get 5 when I want to get 10. Its like count will only stay 10 inside the main, then it changes back to 5. How do I change it so that I can return 10 instead? I tried to get rid of the static in main but then it wouldn't run. Any help is appreciated. Thank you!
Edit: here is the javascript code that receives the returned count value of 5 instead of 10
function update3() {
blah.getCount(function(data) {
dwr.util.setValue("demoReply2", data);
});
I got a question about how to use static, I saw a sample:
public class Exe {
static int i = 47;
public void call() {
for (i = 0; i < 3; i++) {
if (i == 2) {
System.out.println("\n");
}
}
}
public Exe() {
}
public static void main(String[] args) {
Exe t1 = new Exe();
Exe t2 = new Exe();
t2.i = 60;
System.out.println(t1.i);
t1.call();
System.out.println(t2.i);
t2.call();
}
}
When I tried to run it, it printed 60 3, I am wondering why t2.i here is 3, I do not know where the 3 comes from, also, the both results of t1.call() and t2.call() were not printed, please advise, thank you!
for(i=0; i<3;i++){
if(i==2){
System.out.println("\n");
}
}
Your static variable Assigned/incremented here.
Not the i (which you are assuming, it's different) in for loop.
To clear the clouds, Just take another variable called j and do the looping.
for (int j = 0; j < 3; j++) {
if (j == 2) {
System.out.println("\n");
}
}
static means that every instance of the class has access to the same, single instance of the variable.
When you create t1, t1.i is initialized to 47. Then you create t2. t2.i and t1.i are the same variable, so whether you do t1.i = 60 or t2.i = 60, they're BOTH equal to 60.
So before you do t1.call(); or t2.call(), the first thing you do is print out t1.i, which is 60, as per the line t1.i = 60;.
Then you run t1.call() which runs through the for loop. The for loop exits when i can't pass the test i < 3, and since i is an integer, this happens as soon as i is incremented to 3.
After you've run t1.call(), i is now equal to 3. This means both t1.i and t2.i since static means there's only one copy of i across all instances of the Exe class here. So you print out t2.i and it is equal to 3, as it should be.
Hope this helps.
The 3 comes from your for loop, which is reusing the same static int i that you're manually setting to 60 before you call call(). The results of the println probably are being printed, but they're just blank lines.
for (i = 0; i < 3; i++)
In this statement instead of treating i as a local variable it is taken to be class variable which you defined. As for class variables only one copy is maintained for all the instance after the for loop finished(i=3) value of you class variable i remains to be 3.
Your static variable is the same across all objects, this is an effect of static. This means that when you call t2.i = 60; both t1.i and t2.i are set equal to 60. Then when you call t1.call(); you again change both objects. As others have explained your for loop is setting the variable i = 3.
It's because it's a static variable that the assignment affects both objects
Static members doesn't reflect the object state!
All objects of a class will have the same copy(mean to say same value) of the static variables. If one object changes the value of a static variable, since the static variable holds the same value across all the objects, the static variable value will be updated across all the objects of that class. This rule reflects your result.
See the below example:
public class StaticTest {
static int staticA = 10;
int intA;
public StaticTest(int intA){
this.intA = intA;
}
public static void main(String[] args) {
StaticTest test1 = new StaticTest(10);
System.out.println(test1.intA);
System.out.println(test1.staticA);
StaticTest test2 = new StaticTest(20);
System.out.println(test2.intA);
System.out.println(test2.staticA);
}
}
Below is the outpput:
10
10
20
10
This should be relatively straight forward however I'm being swamped in SQL information whenever I search for help with this.
Basically I have 3 classes and they each generate a number and I want to get the total number at the end. Is there a way to make a variable which all 3 classes can add to without generating a SQLite Database?
example
Page1.java creates 5 -> adds to Total
Page2.java creates 12 -> adds to Total
Page3.java creates 10 -> adds to Total
Page4.java opens total
Like I said, its likely a simple problem but SQLite is dominating my searches.
Hope you can help, Thanks.
You can use a static variable for that.
If you don't care about encapsulation you could even use one single public static variable for this purpose.
Example:
private static int mCounter = 0;
public static void addToCounter(int i)
{
mCounter += i;
}
public static int getCount()
{
return mCounter;
}
What you could do would be to have a private value, say, private int count in each of your class and its respective getter. You would then also have a method in each class, say, public void doSomething(){... count = ...}.
Once you have all these, in Page4 you could do something like:
public class Page4
{
Page1 pg1 = new Page1();
Page2 pg2 = new Page2();
Page3 pg3 = new Page3();
pg1.doSomething();
pg2.doSomething();
pg3.doSomething();
int total = pg1.getCount() + pg2.getCount() + pg3.getCount();
}
On the other hand, you could pass in an integer variable to the class which gets modified and passed on to the next class.
You could also pass in a reference to some class which contains the actual counter, and once that each class (Page1, Page2...) has finished doing what it needs it would simply reference that class and update the value itself.
It's not that clear how you call your classes.
However if you have just 3 simple classes and one place to call the classes you could pass your variable between the classes and add the values to it.
public class Page1 {
public void addToVariable(int var) {
var = var + 5;
}
}
public class Page2 {
public void addToVariable(int var) {
var = var + 12;
}
}
...
And then call the class methods with your variable:
int yourVariable = 0;
Page1 p1 = new Page1();
Page2 p2 = new Page2();
p1.addToVariable(yourVariable);
p2.addToVariable(yourVariable);
yourVariable will hold the total you're looking for.