Total Newbie

D

David McCallum

I have defined the following classes:

When the main method is called, Circle.toString is called recursively. The
intention is to use Shape.toString to create the X and Y parts of the
string.

Can anyone tell me why?

public class Shape {
double x;
double y;

Shape(){
x=0;
y=0;
}

Shape(double newX, double newY){
x=newX;
y=newY;
}

public String toString() {
return "X="+new Double(x).toString()+"\n"+
"Y="+new Double(y).toString()+"\n";
}
}

public class Circle extends Shape {
double radius;

Circle(){
super();
}

Circle(double newX, double newY, double newRadius) {
super(newX, newY);
radius=newRadius;
}

public String toString() {
return ((Shape)this).toString()+
"R="+new Double(radius).toString()+"\n";
}

public static void main(String[] args){
Circle c1=new Circle();
Circle c2=new Circle(1, 2, 3);

System.out.println(c1);
System.out.println(c2);
}
}
 
M

Michael Borgwardt

David said:
I have defined the following classes:

When the main method is called, Circle.toString is called recursively. The
intention is to use Shape.toString to create the X and Y parts of the
string.

Can anyone tell me why?

Because of this:
return ((Shape)this).toString()+
"R="+new Double(radius).toString()+"\n";

in Java, instance methods are bound polymorphically at runtime.
The cast to Shape achieves nothing, it still calls the toString
method of that particular *object*, and the object is of class
Circle.

What you do instead is call "super.toString()".

For completeness' sake, this runtime binding does not apply to static
methods or to the selection of overloaded methods in respect to the
parameters' type.
 
D

David McCallum

Michael
What you do instead is call "super.toString()".

Thanks for that, that's what I did, problem is with the following methods
added, calling Circle.equals recurses.

Any clues, I can't see where super would fit in here

David

SHAPE

public boolean equals(Object o){
boolean result=false;
Shape myO;

if (o instanceof Shape) {
myO=(Shape)o;
result=(((this.x==myO.x) && (this.y==myO.y)));
}

return result;
}

CIRCLE

public boolean equals(Object o){
boolean result=true;

if (o instanceof Circle ){
result=result && ((Shape)this).equals((Shape)o);
result=(result && this.radius==((Circle)o).radius);
}
else {
result=false;
}

return result;
}
 
V

VisionSet

David McCallum said:
Michael


Thanks for that, that's what I did, problem is with the following methods
added, calling Circle.equals recurses.

Any clues, I can't see where super would fit in here

because of this line:

return ((Shape)this).toString()+"R="+new Double(radius).toString()+"\n";


what that says is call the toString() method of the current object, since it
is called inside the toString method of the current ovject it recurses.

No doubtably what you intend to happen as already explained is this

return super.toString()+"R="+new Double(radius).toString()+"\n";

this will call the super class toString() method and solve your problem

casting does not change what sort of object it is! You can not make your
Circle object a Shape object, or anything else for that matter, though
technically a Circle object already is a Shape object. Suggest reading up
on inheritence, it does click eventually.
 
N

Niels Dybdahl

Thanks for that, that's what I did, problem is with the following methods
added, calling Circle.equals recurses.
result=result && ((Shape)this).equals((Shape)o);

Try this instead:

if (!super.equals(o))
return false;

Niels Dybdahl
 
M

Michael Borgwardt

David McCallum said:
Michael


Thanks for that, that's what I did, problem is with the following methods
added, calling Circle.equals recurses.

Any clues, I can't see where super would fit in here

You're making *exactly* the same mistake again:
result=result && ((Shape)this).equals((Shape)o);
result=(result && this.radius==((Circle)o).radius);

Please try to understand what I wrote about *why* the problem ocurred.
As a sidenote: casting "this" *never* makes sense in Java.
 
J

Joona I Palaste

You're making *exactly* the same mistake again:
Please try to understand what I wrote about *why* the problem ocurred.
As a sidenote: casting "this" *never* makes sense in Java.

Sure it does:

public class Foo {
public static void main(String[] args) {
new Foo().doAllTheStuff();
}

private void doSomething(Object arg) {
System.out.println("Hello");
}

private void doSomething(Foo arg) {
System.out.println("world!");
}

public void doAllTheStuff() {
doSomething((Object)this);
doSomething(this);
}
}

when executed, this class prints out:

Hello
world!

--
/-- Joona Palaste ([email protected]) ---------------------------\
| Kingpriest of "The Flying Lemon Tree" G++ FR FW+ M- #108 D+ ADA N+++|
| http://www.helsinki.fi/~palaste W++ B OP+ |
\----------------------------------------- Finland rules! ------------/
"Hasta la Vista, Abie!"
- Bart Simpson
 
J

Joona I Palaste

a cast to Object is always nugatory. Everything is also an Object
since Object is the root class of everything.

Did you read the code I snipped away? Did you try it on your own Java
implementation? Did you try adding or deleting (Object) casts on the
doSomething() method calls? Do you understand parameter-type-based
method overloading?

--
/-- Joona Palaste ([email protected]) ---------------------------\
| Kingpriest of "The Flying Lemon Tree" G++ FR FW+ M- #108 D+ ADA N+++|
| http://www.helsinki.fi/~palaste W++ B OP+ |
\----------------------------------------- Finland rules! ------------/
"How come even in my fantasies everyone is a jerk?"
- Daria Morgendorfer
 
J

Joona I Palaste

Did you read the code I snipped away? Did you try it on your own Java
^ should read "you"
implementation? Did you try adding or deleting (Object) casts on the
doSomething() method calls? Do you understand parameter-type-based
method overloading?

--
/-- Joona Palaste ([email protected]) ---------------------------\
| Kingpriest of "The Flying Lemon Tree" G++ FR FW+ M- #108 D+ ADA N+++|
| http://www.helsinki.fi/~palaste W++ B OP+ |
\----------------------------------------- Finland rules! ------------/
"Products like that make me wish I could menstruate."
- Andy Richter
 
C

Chris Uppal

Joona said:
As a sidenote: casting "this" *never* makes sense in Java.

Sure it does:

public class Foo {
...[snipped]


David, you should ignore this stuff for the moment while you learn how to use
"super".

Joona, Roedy, you can also get subtle effects by casting the *receiver* of the
method, since that will affect the space that methods are resolved in. If the
upcast removes "better" matches for an overloaded method then the semantics can
change. E.g. (from an earlier post of mine):

class Super
{
public void
foo(long l)
{
System.out.println("Super.foo(long)");
}
}

public class Sub
extends Super
{
public void
foo(long l)
{
System.out.println("Sub.foo(long)");
}

public void
foo(int i)
{
System.out.println("Sub.foo(int)");
}

public static void
main(String[] args)
{
short s = 22;
Sub it = new Sub();
it.foo(s);
((Super)it).foo(s);
}
}


Which prints out:

Sub.foo(int)
Sub.foo(long)

(And, of course, a cast can make code fail to compile, let alone run without
change:
class Couch
{
void aMethod() { this.aMethod(); } // OK
void anotherMethod() { ((Object)this).aMethod(); } // FAIL
}
but that's hardly surprising.)

-- chris
 
R

Roedy Green

Did you read the code I snipped away? Did you try it on your own Java
implementation? Did you try adding or deleting (Object) casts on the
doSomething() method calls? Do you understand parameter-type-based
method overloading?

Try removing the (Object) cast in your code. It won't make a bit of
difference.


People sometimes suffer under the delusion that:

1. (Object) x actually creates a new smaller object with just the
object fields.


2. ((Dog)aDalmatian).foodType() will use the Dog.foodType method
instead of the Dalmatian.foodType method.

3. It is necessary to cast to a superclass if the parameter wants the
superclass. e.g. neuter( (Dog)aDalmatian );
 
J

Joona I Palaste

Try removing the (Object) cast in your code. It won't make a bit of
difference.

I'm not sure what you're smoking here, but...

[joona@teletran-1 joona]$ cat Foo.java
public class Foo {
public static void main(String[] args) {
new Foo().doAllTheStuff();
}
private void doSomething(Object arg) {
System.out.println("Hello");
}
private void doSomething(Foo arg) {
System.out.println("world!");
}
public void doAllTheStuff() {
doSomething((Object)this);
doSomething(this);
}
}
[joona@teletran-1 joona]$ javac Foo.java
[joona@teletran-1 joona]$ java Foo
Hello
world!
[joona@teletran-1 joona]$
[joona@teletran-1 joona]$ cat Foo.java
public class Foo {
public static void main(String[] args) {
new Foo().doAllTheStuff();
}
private void doSomething(Object arg) {
System.out.println("Hello");
}
private void doSomething(Foo arg) {
System.out.println("world!");
}
public void doAllTheStuff() {
doSomething(/*(Object)*/this);
doSomething(this);
}
}
[joona@teletran-1 joona]$ javac Foo.java
[joona@teletran-1 joona]$ java Foo
world!
world!

Having "Hello" change into "world!" counts as a difference in my book.
Are you sure you're running my code on a real JVM?

--
/-- Joona Palaste ([email protected]) ---------------------------\
| Kingpriest of "The Flying Lemon Tree" G++ FR FW+ M- #108 D+ ADA N+++|
| http://www.helsinki.fi/~palaste W++ B OP+ |
\----------------------------------------- Finland rules! ------------/
"B-but Angus! You're a dragon!"
- Mickey Mouse
 
R

Roedy Green

Joona, Roedy, you can also get subtle effects by casting the *receiver* of the
method, since that will affect the space that methods are resolved in.

I think I see what you are getting at with your (Object) cast. You
are not trying to change the behaviour of that method, just defeat the
intent of the guy who wrote the class to treat Dalmatians specially.

That is a Mickey Mouse thing to do.

It is the exact opposite of what the Nice folk do -- look for a CLOSER
match at run time.
 
M

Michael Borgwardt

Joona said:
Sure it does:

private void doSomething(Object arg) {
System.out.println("Hello");
}

private void doSomething(Foo arg) {
System.out.println("world!");
}

public void doAllTheStuff() {
doSomething((Object)this);
doSomething(this);
}

OK, it has an *effect* in that case, but does it make *sense*?
IMO not, overloading methods in that way only causes confusion
and has little (if any) advantage; the methods should have
different names.
 
J

Jezuch

U¿ytkownik Michael Borgwardt napisa³:
OK, it has an *effect* in that case, but does it make *sense*?
IMO not, overloading methods in that way only causes confusion
and has little (if any) advantage; the methods should have
different names.

But it might be useful with constructors - you can't change constructor's name.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,982
Messages
2,570,186
Members
46,739
Latest member
Clint8040

Latest Threads

Top