Problem with toString accessing variables in constructor x_X
Howdy-hey there folks. I'm having a problem with overriding the toString method in my program and getting it to print local variables found inside of a constructor.
Le snippet:
Code:
public Rectangle(int wi, int he)
{
int width = wi;
int height = he;
int area = width * height;
}
...
public String toString(Object Rectangle)
{
return "width = " + width + "\nlength = " + length + "\narea = " + area;
}
Basically, it's a homework program about rectangles. As you can see with the constructor, it takes two variables as parameters, a width and height of a quadrilateral. In the main of the program, I later make a call to the Rectangle object. If I recall correctly, this should do somethin'-somethin' with the toString method, but I can't figure out how to get the toString to recognize the width, length and area variables.
The error messages are: "cannot find symbol"
I'm also using JCreator LE, if that matters at all.
Any help would be appreciated!
EDIT: This has been SOLVED. I don't know if I can edit my thread title but, if not, can a mod please indicate that this is solved? Thank you.
Re: Problem with toString accessing variables in constructor x_X
your not overriding , you are overloading. The toString method does not take a parameter.You are passing one, this gives the method a different signature.
Re: Problem with toString accessing variables in constructor x_X
^Thank you, I was sure I was going to use some incorrect vocabulary. But what can I do to circumvent this?
Edit: The problem with my program, not my lack of concrete programming vocab :p
Re: Problem with toString accessing variables in constructor x_X
Also your constructor declares local variables width etc. These will not be available to the toString() method.
toString() will use instance variables declared as part of the class. The constructor should assign values to these variables, but not declare new ones which will only confuse matters. The new variables declared in the constructor are said to shadow or hide the instance variables of the class.
Re: Problem with toString accessing variables in constructor x_X
Quote:
Originally Posted by
pbrockway2
The new variables declared in the constructor are said to shadow or hide the instance variables of the class.
Could you explain that bit a little more?
But I think I understand what you're saying. Because I'm declaring local variables inside the constructor, they're gone once the Rectangle has been created and therefore toString can't seem them...right? So, instead, I should maybe just have
Code:
public Rectangle(int wi, int he)
{
int area = wi * he;
}
...and then make "area" a field along with "wi" and "he"?
Re: Problem with toString accessing variables in constructor x_X
You haven't actually posted the code for the class - the declaration of all its bits and pieces. It might be clearer if you did that (with a comment to say *exactly* what you mean each method to do).
But, yes, local variables disappear once a constructor or method finishes. If you want to use a value later make it a field. And once you make it a field *don't* go declaring a local variable with the same name.
Whether you make area a field is entirely up to you. It doesn't actually add any "information" to the rectangle instance. So there will be nothing you can do with this area field that you couldn't do without it.
Code:
class Foo {
private int foo;
public Foo(int f) {
//int foo = f; // No! The foo field is meant
foo = f; // good
}
Re: Problem with toString accessing variables in constructor x_X
You haven't actually posted the code for the class - the declaration of all its bits and pieces. It might be clearer if you did that (with a comment to say *exactly* what you mean each method to do).
But, yes, local variables disappear once a constructor or method finishes. If you want to use a value later make it a field. And once you make it a field *don't* go declaring a local variable with the same name.
Whether you make area a field is entirely up to you. It doesn't actually add any "information" to the rectangle instance. So there will be nothing you can do with this area field that you couldn't do without it.
Code:
class Foo {
private int foo;
private int fooSq;
public Foo(int f) {
//int foo = f; // No! The class's foo field is meant
foo = f; // good
fooSq = foo * foo;
}
/**
* Returns a string describing this Foo.
*/
public String toString() {
return "value=" + foo + " squared=" + fooSq + " cubed=" + (foo * foo * foo);
}
}
Notice how there is a fooSq field for the squared values, but no field is used for the cubed value. It can be done either way.
Notice, too, that the method is documented. In the case of toString() we don't really have a choice about what it does: it returns a string. It does not print a string. If we want a method to print a string we should write one to do that.
Re: Problem with toString accessing variables in constructor x_X
Thank you for the tips. I've fixed a few things and commented the code. Now my problem is that toString just gives me the addresses of the Rectangle objects instead of what my modified toString should be printing.
Here is the code in its entirety:
Code:
import java.util.*;
public class Rectangle
{
private static int wi, he, area; //fields
public Rectangle(int wi, int he) //constructor
{
area = wi * he;
}
public Rectangle() //no-args constructor
{
area = 1;
}
public String toString(Object Rectangle) //a trouble spot; I keep getting addresses when I use toString instead of the below
{
return "width = " + wi + "\nheight = " + he + "\narea = " + area;
}
private static boolean isSquare() //tests if Rectangle is a square (could probably be more eloquent)
{
if (wi == he)
return true;
else
return false;
}
public Rectangle quadratize() //if Rectangle is not a square, this method is supposed to make a square with Rectangle's area
{
wi = (int)(Math.sqrt(area)+.5);
he = wi;
return new Rectangle(wi, he);
}
public static void main(String[] args)
{
Scanner myScanner = new Scanner(System.in);
System.out.println("Please enter positive integers. Non-integers will be truncated.\n");
do //user enters dimensions, do-while is my attempt at getting around negative and non-int values
{
System.out.print("Width? ");
wi = (int)myScanner.nextDouble();
if (wi < 0)
System.out.println("\nPlease enter a non-negative integer.");
}while (wi < 0);
do
{
System.out.print("Height? ");
he = (int)myScanner.nextDouble();
if (he < 0)
System.out.println("\nPlease enter a non-negative integer.");
}while (he < 0);
Rectangle myRectangle = new Rectangle(wi, he); //I make a rectangle
System.out.println("Rectangle: " + myRectangle.toString()); //I attempt to have the rectangle use my modified toString
System.out.println("Is a square? " + isSquare());
if (isSquare()); //if Rectangle is a square, do nothing; if not, make new Rectangle with identical dimensions, then use toString
else
{
Rectangle square = myRectangle.quadratize();
System.out.println("New square of same area dimensions: " + square.toString());
}
}
}
EDIT: Just noticed that some of my comments have been cut off by the BB code. D'oh.
Re: Problem with toString accessing variables in constructor x_X
You're not overriding the toString() method because you've changed the method signature. Java is polymorphic; you can have many methods with the same name so long as the method signature is different.
Take out the parameter you're not even using it.
Re: Problem with toString accessing variables in constructor x_X
Just while I look at it...
(1) Yeah, there's some bug in the forum's css, so it screws up wide code. Best to avoid if you can. (Personally I don't go over 100 chars because I forget, by the end of the line, what the line was about...)
(2) Remove all the "static"s except for main(). Yes the code will break. But the helpful compiler will alert you to things that need to be fixed. Things shouldn't be static unless they are supposed to be static.
Re: Problem with toString accessing variables in constructor x_X
While you look over it, I will mention that removing that "static"s has generated 10 "non-static variable cannot be referenced from a static context" errors, of which I don't think my instructor has explained how to fix (other than making my variables all static).
@ ozzy, you're talking about the toString parameter, right? Alrighty.
Re: Problem with toString accessing variables in constructor x_X
I apologize for the double post but WHOO, removing the toString parameter has fixed my problem. I did, however, have to make my fields and isSquare method static again to remove the other errors. If there can be advice given on how to work around that, that'd be great. Otherwise, things seems to be working now.
Thank you, everyone.
Re: Problem with toString accessing variables in constructor x_X
Yes, to override a method from a super you need to keep the method signature.
This is the toString method signature:
public String toString();
This is your method signature:
public String toString(Object obj);
Two different methods with the same name.
Re: Problem with toString accessing variables in constructor x_X
Honestly, you can remove the static declarations and deal with the resulting errors. The compiler is telling you useful things about your code: like you didn't initialise all the fields with your constructor, or you aren't calling methods like isSquare() with the instance of rectangle you wish to check.
Probably spoonfeeding, but if you remove the static keywords and deal with the resulting messages, you'll end up with something like
Code:
import java.util.*;
public class Rectangle
{
private int wi, he, area;
/** Constructs a rectangle of given dimensions. */
public Rectangle(int wi, int he)
{
this.wi = wi; // the constructor's job is to assign the
this.he = he; // fields with good values
area = wi * he;
}
public String toString()
{
return "width = " + wi + "\nheight = " + he + "\narea = " + area;
}
/** Returns true iff the rectangle is a square. */
private boolean isSquare()
{
return wi == he;
}
/** Returns a square roughly similar in size to this rectangle. */
public Rectangle quadratize()
{
wi = (int)(Math.sqrt(area)+.5);
he = wi;
return new Rectangle(wi, he);
}
public static void main(String[] args)
{
Scanner myScanner = new Scanner(System.in);
System.out.println("Please enter positive integers. Non-integers will be truncated.\n");
int width; // local variables used for input
int height;
do
{
System.out.print("Width? ");
width = (int)myScanner.nextDouble();
if (width < 0)
{
System.out.println("\nPlease enter a non-negative integer.");
}
}while (width < 0);
do
{
System.out.print("Height? ");
height = (int)myScanner.nextDouble();
if (height < 0)
{
System.out.println("\nPlease enter a non-negative integer.");
}
}while (height < 0);
Rectangle myRectangle = new Rectangle(width, height);
System.out.println("Rectangle: " + myRectangle.toString());
System.out.println("Is a square? " + myRectangle.isSquare()); // note use of instance to access the method
if (!myRectangle.isSquare()) // ditto
{
Rectangle square = myRectangle.quadratize();
System.out.println("New square of same area dimensions: " + square.toString());
}
}
}