Comp Sci How can I fix errors in my Java Complex Number Class Homework?

Click For Summary
The discussion revolves around fixing errors in a Java class designed to represent complex numbers. Key issues include incorrect constructor implementations, improper use of instance variables, and misunderstandings regarding method accessibility and return types. Suggestions include correcting the constructors to properly initialize double values, simplifying the magnitude calculation method, and ensuring the sum method returns a new complex number instead of attempting to convert local variables to strings. The conversation highlights the importance of understanding scope and access modifiers in Java programming. Overall, the user is encouraged to refine their code and grasp object-oriented principles better.
  • #31
voko said:
Code:
{
   // scope A

   int a;
   int b;

   {
       // scope B - nested in A

       int a;

       {
            // scope C - nested in A nested in B

            int b;
       }
    }

    {
        // scope D - nested in A

        int b;
    }
}
This does not compile. The a and b defined in Scope A are visible throughout and cannot be redefined.
voko said:
Now, even though I said that an outer scope's variables eclipsed by an inner scope's variables are inaccessible, there is a way to use the class scope variables by referencing them via this, but that can only be done in a non-static member function (because static members do not have this to begin with).
Not true. Static, class level variables can be accessed via 'this'. It just isn't correct to do so because the value is applicable to all of the classes that you have created and not just one particular instance. IDEs and compilers will warn you about it (Static member accessed via instance reference) but the code will compile and function properly.
CAF123 said:
I am not sure what you mean by 'using my one shot at reusing the class level variable name'.
Think of it as saying "while I'm in this method, I don't care that there is a class level variable x. I want x to be something else". If you haven't made x to "be something else", x and this.x both refer to the class level variable. Once you decide to make it something else, only this.x will refer to the class level version (within the current scope).
CAF123 said:
I don't think I understand this paragraph fully. Does it not contradict the comments after the code:
Code:
x = superman;	// The incoming variable superman is being used to set the class level variable x
So x = superman; sets the local variable superman to the class level variable x? x = superman; sets the class level variable, (as written in the comment after the code) but above you say this.x modifies it.
superman is on the right side. You aren't setting superman, you're setting x. There is no local variable x that exists at that point so x and this.x both refer the same thing (the class level x). The compiler doesn't look ahead to see that you're going to create a local version of x on the next line.

CAF123 said:
Why would you put the String in between those brackets? I don't think I have grasped this part either.
The brackets could represent anything that has brackets like an if statement, a for loop, or just a set of brackets. The brackets define a scope that is walled off from other areas. Inside the scope, the compiler knows what has been defined previously but can't look inside other bracketed areas.

CAF123 said:
I appreciate your help, but I don't feel like I understood it as well as the other examples. One question that sprung to mind was why reuse variables?
Because it makes the code easier to understand? You're not really reusing the variables, just their names. Yeah, I know that doesn't make sense yet...

Here's another example of scope within a method. I am going to ignore the whole x vs. this.x issue. For now, I'm just showing you a single method. I'm also using all new variable names because I don't want you thinking about anything previously discussed. Just try to understand what is going on with the variable u.

Let's say that we have a class level variable s that can be modified by other methods in your class and we need a method to perform different actions depending on the current value of s. In this method, I am not modifying the value of s. However, I am creating a variable t at the beginning and defining a variable u in the two sections of an if/else statement. As far as the compiler is concerned, u can be defined inside either of the brackets because it wasn't defined earlier (like t). Creating another u within the else statement isn't a problem because even though it can look back for previously defined variables, it can't peek inside the brackets. As far as the code in the else brackets is concerned, u has not been defined yet (it can't see inside of the if brackets while it's inside of the else brackets).
Code:
int s = 10;	// Some class level variable

public int someRandomMethod(){
	int t = 2;

	if (s > 100){
		int u = 2 / s;
		if(u > 250){
			return u;	// Leave the method and return the value of u
		}
		// If u <= 250 the code will leave the if/else block and continue at the EXIT POINT
	}
	else{						// If s was greater than 100, it won't go in here
		int u = (10 * t) - s;
		if(u < 25){
			return u;
		}
		// If u <= 25 the code will leave the if/else block and continue at the EXIT POINT
	}
	// EXIT POINT

	// The compiler knows about s and t
	// The compiler does not know about u at this point because it can't look up and into brackets
	return 0;
}
Do you see why the compiler doesn't know about u at the end?
 
Last edited:
Physics news on Phys.org
  • #32
Borg said:
This does not compile. The a and b defined in Scope A are visible throughout and cannot be redefined.

Even if scope A is a class and scopes B and D are its member functions, or scope A is a member function, and B and D are nested classes, or some other interesting situation?

I mentioned that some (hopefully, good) book is needed, the rules of shadowing in Java are quite complicated. Scoping, however, is simple as a concept, and that was what I wanted to demonstrate.
 
  • #33
voko said:
Even if scope A is a class and scopes B and D are its member functions, or scope A is a member function, and B and D are nested classes, or some other interesting situation?
If scope A is a class - yes but, only in that case. If you put that block of code within a method, it breaks. For now, let's try to get CAF123 to understand scope within a method and expand from there.
 
  • #34
Borg said:
If scope A is a class - yes but, only in that case.

This is not the only case. If scope A is a member, and the member defines inner classes, the inner classes may contain variables that shadow scope A's variables. There may be some other situations as well, my knowledge of Java is, admittedly, rusty.

Let me rectify my earlier statements: scoped variables, provided the code compiles, work the way I indicated earlier: visible within the scope they are defined in, and visible in nested scopes as well, unless they are shadowed (when this is allowed) by an identically named variable defined in a nested scope, and the same rules apply to the shadowing variables.
 
  • #35
voko said:
This is not the only case. If scope A is a member, and the member defines inner classes, the inner classes may contain variables that shadow scope A's variables. There may be some other situations as well, my knowledge of Java is, admittedly, rusty.

Let me rectify my earlier statements: scoped variables, provided the code compiles, work the way I indicated earlier: visible within the scope they are defined in, and visible in nested scopes as well, unless they are shadowed (when this is allowed) by an identically named variable defined in a nested scope, and the same rules apply to the shadowing variables.
Because you didn't clarify your example as a special case that only applied where the scope of A was at the class level, I assumed that you were referring to the general case that could be used anywhere.

I'm not sure by what you mean by Scope A is a "member" of, other than being a member of a class as we've both stated. I'll bet CAF123 hasn't been introduced to inner classes yet so I really didn't want to go there.

Interesting. Even though that's what we are discussing, I never saw the term 'shadowing' before today. Never too old to learn new things.
 
  • #36
Yeah, I just wanted to clarify the concept of scopes and how they affect visibility of variables in most general terms, without getting into the complexity of when shadowing is actually permissible.
 
  • #37
Borg said:
Code:
int s = 10;	// Some class level variable

public int someRandomMethod(){
	int t = 2;

	if (s > 100){
		int u = 2 / s;
		if(u > 250){
			return u;	// Leave the method and return the value of u
		}
		// If u <= 250 the code will leave the if/else block and continue at the EXIT POINT
	}
	else{						// If s was greater than 100, it won't go in here
		int u = (10 * t) - s;
		if(u < 25){
			return u;
		}
		// If u <= 25 the code will leave the if/else block and continue at the EXIT POINT
	}
	// EXIT POINT

	// The compiler knows about s and t
	// The compiler does not know about u at this point because it can't look up and into brackets
	return 0;
}
Do you see why the compiler doesn't know about u at the end?

Yes, because u was defined within a set of brackets. The value of u used depends only on the value of s used. If s > 100, then u = 2/s is used. If s <= 100, (which since s = 10, is the case here), u = 10t -s. When the if/else block is finished, the compiler does not know about u.

What is the purpose of the return 0; statement?
Code:
...
            return 0;
}
After this final }, the compiler no longer knows about t (since it is defined within the method), but still knows about s since it is class level.
 
  • #38
CAF123 said:
Yes, because u was defined within a set of brackets. The value of u used depends only on the value of s used. If s > 100, then u = 2/s is used. If s <= 100, (which since s = 10, is the case here), u = 10t -s
Don't worry about the calcuation or value of s. It's just an example. According to the initial description, s may have changed before the method is called.

CAF123 said:
What is the purpose of the return 0; statement?
Code:
...
            return 0;
}
The method requires you to return an int (i.e. public int someRandomMethod()). If it makes it all the way to the end, it has to return an int. I just hardcoded a 0 as a default.

CAF123 said:
After this final }, the compiler no longer knows about t (since it is defined within the method), but still knows about s since it is class level.
Yes, correct! :smile:

Now, can you tell me other places where you can and cannot put "int u" declarations without breaking the current example?

Could you declare it at the class level?

If so, how would references to both u's need to be handled in the method?

Can you declare it in other places within the method?

If so, where and why? Remember - without breaking the current example.

How do the changes affect what the compiler knows at different places?
 
  • #39
Borg said:
Now, can you tell me other places where you can and cannot put "int u" declarations without breaking the current example?

Could you declare it at the class level?

If so, how would references to both u's need to be handled in the method?

Can you declare it in other places within the method?

If so, where and why? Remember - without breaking the current example.

How do the changes affect what the compiler knows at different places?

I think you can have the same effect by using Boolean statements:
Code:
Console myConsole = System.console();
String S = myConsole.readLine("Enter an integer value for s:");

int s = Integer.parseInt("S");

boolean condition1;
int u = 2/s;

condition1 = s > 100;

int p = 10*t - s; //All of this in the class, outwith the method.

public int someRandomMethod() {
       int t = 2;
       
       if (condition1) {
                 return u;
     }else {
                 return p;
}
     return 0;
}
I realize I have introduced another variable p and set a condition on s, but is it ok?
 
Last edited:
  • #40
CAF123 said:
I think you can have the same effect by using Boolean statements:
Code:
Console myConsole = System.console();
String S = myConsole.readLine("Enter an integer value for s:");

int s = Integer.parseInt("S");

boolean condition1;
int u = 2/s;

condition1 = s > 100;

int p = 10*t - s; //All of this in the class, outwith the method.

public int someRandomMethod() {
       int t = 2;
       
       if (condition1) {
                 return u;
     }else {
                 return p;
}
     return 0;
}
I realize I have introduced another variable p and set a condition on s, but is it ok?
I'm not sure what you're asking is OK. There is always a different way to write any program. My goal is just to describe how variables are scoped.

The main problem above is that while you can redefine a class level s inside of a method, you can't set it to something different within the scope of where you've declared it. You are attempting to define s four times at the class level. You can't do that.

BTW, It's good practice to compile every once in a while to make sure that you haven't introduced errors like that. Since you're just starting, I would perform test compiles more often. Of course when you do that, you have to make sure that all of your methods return something if they're not set to void.

Let's look at my example again. I've added four new declarations for u in multiple places and commented them out. Try uncommenting them one at a time and recompiling to see what works and what doesn't. Don't pay attention to whether or not it's logical to put u in any place or another - just focus on whether or not the compiler will allow it.

Code:
public static int s = 10;	// Some class level variable
//	private int u = 0;

public int someRandomMethod() {
	int t = 2;
//	int u = 0;

	if (s > 100) {
		int u = 2 / s;
		if (u > 250) {
			return u;	// Leave the method and return the value of u
		}
		// If u <= 250 the code will leave the if/else block and continue at the EXIT POINT
	}
	else {						// If s was greater than 100, it won't go in here
		int u = (10 * t) - s;
		if (u < 25) {
			return u;
		}
		// If u <= 25 the code will leave the if/else block and continue at the EXIT POINT
//		int u = 0;
	}
	// EXIT POINT

	// The compiler knows about s and t
	// The compiler does not know about u at this point because it can't look up and into brackets
//	int u = 0;
	return 0;
}
 
  • #41
Borg said:
The main problem above is that while you can redefine a class level s inside of a method, you can't set it to something different within the scope of where you've declared it. You are attempting to define s [STRIKE]four[/STRIKE] two times at the class level. You can't do that.
Just noticed that I wrote four.
 
  • #42
Hi Borg,
I have tried what you asked and I have found the code compiled with two placings of u. I have put reasons commented in the code:
Code:
public class Random1 {

public static int s = 10;	// Some class level variable
//	private int u = 0;      //will compile if placed here - while in method, we don't care there exists a class level varriable called u- if want to refer to class level, use this. construct.

public int someRandomMethod() {
	int t = 2;
//	int u = 0; //u cannot go here since it is again defined intu=2/s and intu=10t-s within the method.

	if (s > 100) {
		int u = 2 / s;
		if (u > 250) {
			return u;	// Leave the method and return the value of u
		}
		// If u <= 250 the code will leave the if/else block and continue at the EXIT POINT
	}
	else {						// If s was greater than 100, it won't go in here
		int u = (10 * t) - s;
		if (u < 25) {
			return u;
		}
		// If u <= 25 the code will leave the if/else block and continue at the EXIT POINT
//		int u = 0; //u cannot go here since it is already defined inside method.(i.e int u = 2/s above or int u = 10t-s)
	}
	// EXIT POINT

	// The compiler knows about s and t
	// The compiler does not know about u at this point because it can't look up and into brackets
//	int u = 0; //ok to have here since u (private int u) defined outside method and intu=2/s and intu=10t-s defined inside brackets so compiler does not know about them.
	return 0;
} //close method
}
 
  • #43
Borg said:
Just noticed that I wrote four.

At what two instances have I defined s? I tried to compile this and only 1 error appeared in the line condtion1 = s > 100; What I have tried to do here is make a Boolean condition, but perhaps what I wrote down does not qualify as a statement in Java.
 
  • #44
CAF123 said:
Hi Borg,
I have tried what you asked and I have found the code compiled with two placings of u. I have put reasons commented in the code:
Yes, that's all correct - very good. Does it all make better sense now how variables are visible to the compiler throughout a class?
 
  • #45
CAF123 said:
At what two instances have I defined s? I tried to compile this and only 1 error appeared in the line condtion1 = s > 100; What I have tried to do here is make a Boolean condition, but perhaps what I wrote down does not qualify as a statement in Java.
I misread your code. I see now that one of the variables is a capital S. By normal conventions, variables are Camel Case where the first word starts with a non-capitalized letter. I guess that caused me to see it wrong. The convention for class names is Camel Case where the first word starts with a capitalized letter. It makes it easier to read declarations like this:

Class...variable...Class
MyClass myClass = new MyClass();
 
  • #46
CAF123 said:
At what two instances have I defined s? I tried to compile this and only 1 error appeared in the line condtion1 = s > 100; What I have tried to do here is make a Boolean condition, but perhaps what I wrote down does not qualify as a statement in Java.

String S = myConsole.readLine("Enter an integer value for s:");
int s = Integer.parseInt("S");

The above statement for int s says that you want to parse the letter S and not the variable S. This is what confused me earlier when I thought that you were trying to parse a 5. It should be written this way (no quotes):
int s = Integer.parseInt(S);

For condition1, you can define condition1 = s > 100 but you can't split it when declaring it at the class level. Change this:
boolean condition1;

condition1 = s > 100;

To this:
boolean condition1 = s > 100;
 
  • #47
I am having some difficulty in writing the code to produce some output. What I have is:
Code:
import java.io.Console;


public class Random {

int s = s;

boolean condition1 = s > 100;

int u = 2/s;

int t = 2;

int p = 10*t - s; //All of this in the class, outwith the method.

public int someRandomMethod() {
       
       
       if (condition1) {
                 return u;
     }else {
                 return p;
}
     
}

public static void main(String args[]) {


String S = myConsole.readLine("Enter an integer value for s:");
int s = Integer.parseInt(S);



}
}

I am not sure how to reference the method here. I think my next line in main method is something like myConsole.printf("The value returned is ...(reference method));, but I don't quite see how to do this. I realize this is off topic but I would like to see how to work the code.
Thanks.
 
  • #48
Three main problems.

One, you haven't declared an instance of your class in main so there's no way to interact with an instance of it.

Two, move all of your variables into someRandomMethod(). The variables at class level get set when an instance of the class is created. From your code, it looks like you want to perform an action on those variables when you call the someRandomMethod() method.

Fix those two and the third might be more apparent.
 

Similar threads

  • · Replies 2 ·
Replies
2
Views
2K
  • · Replies 3 ·
Replies
3
Views
2K
  • · Replies 12 ·
Replies
12
Views
2K
  • · Replies 4 ·
Replies
4
Views
2K
  • · Replies 2 ·
Replies
2
Views
2K
  • · Replies 5 ·
Replies
5
Views
3K
  • · Replies 2 ·
Replies
2
Views
7K
  • · Replies 1 ·
Replies
1
Views
2K
  • · Replies 23 ·
Replies
23
Views
6K
  • · Replies 2 ·
Replies
2
Views
4K