i am trying to grasp the idea of ObjectOriented programing can someone explain why the local variable (a) prints zero instead of the set int that is placed in the getter and setter.
These are the objects in the AppClass
Symptoms obj = new Symptoms();
test obj2 = new test();
actionPerformed... i think this is all you need from the AppClass
#Override
public void actionPerformed(ActionEvent e) {
int x = Integer.parseInt((field.getText()));
obj.setSleep(x);
writeSleep();
frame.setVisible(false);
obj2.tester();
readSleep();
initialize2();
}
This is the Symptoms class that i hope to add more symptoms if i can get this to work
public class Symptoms {
private int sleep;
public int getSleep() {
return sleep;
}
public void setSleep(int sleep) {
this.sleep = sleep;
}
}
this is the tester class where i hope to print out the value of (a)
public class test {
public void tester(){
Symptoms get = new Symptoms();
int a;
a = get.getSleep();
System.out.println(a);
}
}
It seems as tho the test class isnt getting the "message" but if i run the same code in the AppClass, given i modify the code a little bit, then (a) will print.
Because the JLS says so, see chapter 4.12.5. Initial Values of Variables:
Each class variable, instance variable, or array component is initialized with a default value when it is created (§15.9, §15.10):
For type int, the default value is zero, that is, 0.
Now after you saw it's confusing, I recommend you to explicitly set it to zero in the future, it's clearer.
In test.tester(), an instance of Symptoms is created and the method setSleep() is never called with it, so getSleep returns the default value of a, which is 0.
You only ever call setSleep in obj.setSleep(x);, where obj is an entirely different instance from get. But since x is not static, calling obj.setSleep doesn't change the value of get.x -- only the value of obj.x.
here is a better version of the question and the answer. It has nothing to do with setting int to zero.
How to set and get with three Classes?
Related
Preface
I'd like to saying two things:
I don't know how to phrase this question in a few words. So I can't find what I'm looking for when searching (on stackoverflow). Essentially, I apologize if this is a duplicate.
I've only been programming Java consistently for a month or so. So I apologize if I asked an obvious question.
Question
I would like to have a method with a parameter that holds (path to) an integer.
How is such a method implemented in Java code?
Restrictions
The parameter should be generic.
So, when there are multiple of that integer variables, the correct one can be used as argument to the method, when it is called (at runtime).
My Idea as Pseudo-Code
Here's the idea of what I want (in pseudo-code). The idea basically consist of 3 parts:
the method with parameter
the variables holding integer values
the calls of the method with concrete values
(A) Method
.
Following is the definition of my method named hey with generic parameter named pathToAnyInteger of type genericPathToInt:
class main {
method hey(genericPathToInt pathToAnyInteger) {
System.out.println(pathToAnyInteger);
}
}
(B) Multiple Integer Variables
Following are the multiple integer variables (e.g. A and B; each holding an integer):
class A {
myInt = 2;
}
class B {
myInt = 8;
}
(C) Method-calls at runtime
Following is my main-method that gets executed when the program runs. So at runtime the (1) previously defined method hey is called using (2) each of the variables that are holding the different integer values:
class declare {
main() {
hey("hey " + A.myInt);
hey("hey " + B.myInt);
}
}
Expected output
//output
hey 2
hey 8
Personal Remark
Again, sorry if this is a duplicate, and sorry if this is a stupid question. If you need further clarification, I'd be willing to help. Any help is appreciated. And hey, if you're going to be unkind (mostly insults, but implied tone too) in your answer, don't answer, even if you have the solution. Your help isn't wanted. Thanks! :)
Java (since Java 8) contains elements of functional programing which allows for something similiar to what you are looking for. Your hey method could look like this:
void hey(Supplier<Integer> integerSupplier) {
System.out.printl("Hey" + integerSupplier.get());
}
This method declares a parameter that can be "a method call that will return an Integer".
You can call this method and pass it a so called lambda expression, like this:
hey(() -> myObject.getInt());
Or, in some cases, you can use a so called method referrence like :
Hey(myObject::getInt)
In this case both would mean "call the hey method and when it needs an integer, call getInt to retrieve it". The lambda expression would also allow you to reference a field directly, but having fields exposed is considered a bad practise.
If i understood your question correctly, you need to use inheritance to achive what you are looking for.
let's start with creating a hierarchy:
class SuperInteger {
int val;
//additional attributes that you would need.
public SuperInteger(int val) {
this.val = val;
}
public void printValue() {
System.out.println("The Value is :"+this.value);
}
}
class SubIntA extends SuperInteger {
//this inherits "val" and you can add additional unique attributes/behavior to it
public SubIntA(int val) {
super(val);
}
#override
public void printValue() {
System.out.println("A Value is :"+this.value);
}
}
class SubIntB extends SuperInteger {
//this inherits "val" and you can add additional unique attributes/behavior to it
public SubIntB(int val) {
super(val);
}
#override
public void printValue() {
System.out.println("B Value is :"+this.value);
}
}
Now you method Signature can be accepting and parameter of type SuperInteger and while calling the method, you can be passing SubIntA/SuperInteger/SubIntB because Java Implicitly Upcasts for you.
so:
public void testMethod(SuperInteger abc) {
a.val = 3;
a.printValue();
}
can be called from main using:
public static void main(String args[]){
testMethod(new SubIntA(0));
testMethod(new SubIntB(1));
testMethod(new SuperInteger(2));
}
getting an Output like:
A Value is :3
B Value is :3
The Value is :3
Integers in Java are primitive types, which are passed by value. So you don't really pass the "path" to the integer, you pass the actual value. Objects, on the other hand, are passed by reference.
Your pseudo-code would work in Java with a few modifications. The code assumes all classes are in the same package, otherwise you would need to make everything public (or another access modifier depending on the use case).
// First letter of a class name should be uppercase
class MainClass {
// the method takes one parameter of type integer, who we will call inputInteger
// (method-scoped only)
static void hey(int inputInteger) {
System.out.println("hey " + inputInteger);
}
}
class A {
// instance variable
int myInt = 2;
}
class B {
// instance variable
int myInt = 8;
}
class Declare {
public static void main() {
// Instantiate instances of A and B classes
A aObject = new A();
B bObject = new B();
// call the static method
MainClass.hey(aObject.myInt);
MainClass.hey(bObject.myInt);
}
}
//output
hey 2
hey 8
This code first defines the class MainClass, which contains your method hey. I made the method static in order to be able to just call it as MainClass.hey(). If it was not static, you would need to instantiate a MainClass object in the Declare class and then call the method on that object. For example:
...
MainClass mainClassObject = new MainClass();
mainClassObject.hey(aObject.myInt);
...
Ok I'm sure this is simple, but I'm having issues and my mind is blank. =(
I know 'final' makes it so the variable can't change but that's pretty much all I can figure out about it right now.
And the code...
If I take out the 'final' the error comes up as "error: missing return statement
}" for the first two methods.
EDIT: Thank you all for the help, surprising how fast I got help!
So I just took out 'final' and added 'void' to the first two methods. I'm sure it'll take some time to fully understand everything, but it definitely helps.
There is a part two and here is the part that I have no clue on what to do...
The second part you just have to test this first program. Am I supposed to make a separate file with the same code?
If anyone can help great, but if not thats fine I'll work on it later.
You declare your function as
public static int removeOneFromRoom (int number)
{
totalNumber = totalNumber-number;
}
The emphasis here is the public static int, telling the compiler that your function is supposed to return an integer. You do however not return anything in that function body, so the compiler complains rightfully. Either return something, or declare the return value as void.
Maybe you're missing the return statement for the first two methods. Or you may want to change the return type to void if you don't need to return anything.
Doing these will remove your error but it might differ from what you need.
public static void addOneToRoom(int number)
{
numberInRoom = numberInRoom+number;
}
public static void removeOneFromRoom (int number)
{
totalNumber = totalNumber-number;
}
Hope this helps.
A variable declared with static and final keywords behaves like a constant. But what does that mean ?
It means you can't change their values. In simpler terms if variable is a primitive then you can't change its value but if its a reference variable then you can't change the reference to some other address.
So in your code, declaring numberInRoom and totalNumber variables as static and final is wrong
public static int numberInRoom=3;
public static int totalNumber=30;
public static int addOneToRoom(int number)
{
numberInRoom = numberInRoom+number;
}
public static int removeOneFromRoom (int number)
{
totalNumber = totalNumber-number;
}
Are you sure that you want these variables to be declared as static because such variables shall be shared by all instances of the concerned class. Please have a look at what does declaring variables as static and final means
I need to know how to call a variable from one method to another
Can anyone help me?
public static void number(){
number = 1;
}
public static void callNumber(){
/*How can I call number to this method???
*/
}
Actually, "call a variable from an other method" is not very explicit, since a variable in a method is either global (used in the method but naturally available in the entire program), or a local variable of the method.
And in this last situation it is impossible to get this value.
Then either you declare your variable externally and it is trivial, or you specifiy a type value to your method "number()":
public static int number() {
int number = ...;
return number;
}
and you call it:
public static void callNumber() {
int numberReturned = number();
// other things...
}
Note: your code number = 1; specifies that your variable is global...
The trick is to set "number" available either by the return of the method, or by specifying this variable global.
I don't know if I've answered your question, if not try to be more explicit.
Between static methods, variables can be shared by making them global,
or by sending them as parameters(noas described by #Gaétan Séchaud).
However, if those two methods has a continuos connection between them, and they handle some variables needed to be shared, it smells like a class is needed.
In Java, you don't have declare a method physically before you use it. The same thing doesn't apply for variables.
Why is this the case? Is it just for "legacy" reason (ie., the Java's creators didn't feel like doing it), or is it just not possible?
Eg.,
public class Test
{
// It is OK for meth1 to invoke meth2
public void meth1() { meth2(); }
public void meth2() { }
// But why is it NOT ok for field1 to reference field2
private int field1 = field2;
private int field2 = 3;
}
If I wanted my Java compiler to support this kind of forward-reference, what is the general idea as to how to do it?
I understand there'd be issue about circular depencies, which we'd need to be careful about. But other than that, I really don't see why it should not be possible.
[Edit]Ok, here's my initial thought as to how to do this.
While analysing the code, the compiler would build a graph of dependencies for the variables in the given scope. And if it sees a loop (ie., int a = b; int b = a), then it would throw an error. If there is no loops, then there must be some optimal way to re-arrange the statements (behind the scence) such that a field will only reference fields declared before it, and so it shouuld try to figure out the order. I haven't worked out the exact algorithm, but I think it is possible. Unless someone can scientifically prove me wrong.
Recap the question:
Say I'm trying to build my own dialect of Java, which supports this sort of scoping. My main question is, could you give me some ideas as to how to do this
Thanks
According to the JLS, Section 12.4.1, initialization of class variables proceeds from top to bottom, in "textual order":
The static initializers and class variable initializers are executed in textual order, and may not refer to class variables declared in the class whose declarations appear textually after the use, even though these class variables are in scope (§8.3.2.3). This restriction is designed to detect, at compile time, most circular or otherwise malformed initializations.
So, if you make your own compiler to recognize forward class variable declarations, then it is violating the Java Language Specification.
I will give you a simple piece of code:
public class Test
{
private int foo = bar;
private int bar = foo;
}
What would you expect this to do?
I presume that designers of Java has done it so because assignment of values to instance variables must be executed in some order. In the case of Java, they are executed downwards (from up to bottom).
EDIT
What about this?
public class Test {
private int foo = quu++;
private int bar = quu++;
private int quu = 1;
}
What values would foo and bar have? Which quu++ statement would be executed first?
My point is, Java designers must have thought that it is counter intuitive to do it as you did describe in your question, i.e. unordered execution with compile time code analysis.
FINAL EDIT
Let's complicate things:
class Test {
private James james = new James(anInt);
private Jesse jesse = new Jesse(anInt);
private IntWrapper anInt = new IntWrapper();
}
class James {
public James(IntWrapper anInt) {
if(--anInt.value != 0) {
new Jesse(anInt);
}
else {
anInt.isJames = true;
}
}
}
class Jesse {
public Jesse(IntWrapper anInt) {
if(--anInt.value != 0) {
new James(anInt);
}
else {
anInt.isJames = false;
}
}
}
class IntWrapper {
public int value = 99;
public boolean isJames;
}
I am not sure what it proves regarding your question because I am not sure about your point.
There is no circular dependency here but value of an instance variable of IntWrapper, isJames, depends on the execution order and it might be difficult to detect this kind of stuff with a lexical/semantic analyzer.
How will field1 know value of field2 before it has been defined and assigned a value?
It has to do with the order of initialization. Fields are initialized top to bottom. In your example, when field1 tries to reference field2 in the initializer, the latter is yet to be initialized itself.
The rule about forward references is aimed at catching the most obvious cases of this problem. It does not catch all; for example, you can still do:
private int field1 = getField2();
private int field2 = 3;
private int getField2() { return field2; }
and get field1 intialized to zero where you might be expecting 3.
I am not able to understand flow of control in the following code:
class Television {
private int channel=setChannel(7);
public Television (int channel) {
this.channel=channel;
System.out.println(channel + "");
}
public int setChannel(int channel) {
this.channel=channel;
System.out.print(channel + " ");
return channel;
}
}
public class TelevisionMain {
public static void main(String[] args) {
Television t = new Television(12);
}
}
The output is 7 12.
It means explicit invocation occurs first.
I am new to java and I thought that execution starts from main so the constructor should have been invoked first.
Can anyone please explain why this happens.
initialisation is part of construction and it is defined to occur after the super() has been called and before the body of the constructor.
the constructor should have been invoked first.
It is. The field initialisation is part of the constructor.
Your Television constructor is compiled to roughly:
public Television(int channel)
{
super();
this.channel = this.setChannel(7);
this.channel = channel;
System.out.println(channel+"");
}
So when you call Television t = new Television(12);, it first sets the channel to 7, then 12.
Ultimately the answer is because the specification says it should. However it is reasonable that it be this way round because to behave the otherway round would make it impossible to overwrite a default initialed value
If the order were constructor first then everything else, then the order would be
called Television(12)
channel set to 12 within constructor
channel set back to 7 by int channel=setChannel(7);
This is clearly an unreasonable state of affairs as you could never use default values because these default values could not be changed by a constructor
In Java there is essentially a hidden default constructor. If you don't declare one, you can initialize a variable at the top of a class with a default variable. That's the way we like to think of it anyways. The reality is that each class has a static block where variables can be declared and played with before actual constructor declaration hits during the class load process.
I feel like your above declaration is similar to this, and that is why you are seeing the output 7 12.
class Television {
//The below code is essentially equal to your declaration of
// private int channel = setChannel(7);
private int channel;
static{
//This occurs before constructor call during class load.
channel = setChannel(7);
}
....
}
A better explanation can be found in the java tutorials on Initializing Fields