Interfaces and the toString method

M

Michael Preminger

I have defined and Interface

public interface HasChildren{
public int getNumberOfChildren();
public void setNumberOfChildren(int numberOfChildren);

}

and let a class, Student, implement it, like this:

class Student extends Person implements HasChildren{

public String toString(){
//....
}
}

In a test class I have a method:

public void giveBirth(HasChildren hc){

}

hc has no access to other methods defined in Student except the two
methods defined in HasChildren, which I understand.
To my surprise I see that the object hc has access to the method
toString(), even though it is not part of the interface definition.

This seem to be the case also for other methods inherited from class Object

The way I understand, interfaces are not descendent of any
superinterface by default. How does class Object come in there?

Thanks

Michael

Michael
 
S

SPG

All implementations of any interface still eventually extend the Object
type.
This is the way java works..

If it is not an Object, how can you instantiate it?
 
D

David Van de Voorde

If you look to an Interface as a "full abstract class", it will probably
make more sense to you.

And indeed, the Object API Docs say: "Every class has Object as a
superclass. All objects, including arrays, implement the methods of this
class."

David.
 
P

Paul van Rossem

All implementations of any interface still eventually extend the Object
type.
This is the way java works..

If it is not an Object, how can you instantiate it?
Strictly speaking, it is not the implementation of the interface that
defines the toString() method, but the Student class that extends the
Person class, which in its turn extends the Object class.
Paul.
 
C

Chris Uppal

Michael said:
hc has no access to other methods defined in Student except the two
methods defined in HasChildren, which I understand.
To my surprise I see that the object hc has access to the method
toString(), even though it is not part of the interface definition.

You are right to be surprised. This oddity (which is how Java is defined to
work) is the result of a specific hack in the definition of the Java type
system. The reasoning is that since anything that implements an interface must
(by definition) be an instance (of a subclass) of java.lang.Object, the type
system knows that all interfaces implicitly "extend" Object. This hack applies
/only/ to the methods of Object.

A singularly gross hack IMO, but then I'm something of a purist...

-- chris
 
M

Michael Preminger

All implementations of any interface still eventually extend the Object
type.
This is the way java works..

If it is not an Object, how can you instantiate it?

I instantiate is as new Student() not new HasChildren().
When a method only knows it is an object of type HasChildren(), I expect
it not to know that it is anything else. (that's one of the fine things
about interfaces). But reading through the rest of the thread I realize
that the methods defined in Object (toString(), hashCode(), equals()
a.s.o) are an exception to this rule.

Michael
 
M

Michael Preminger

Michael Preminger wrote:




You are right to be surprised. This oddity (which is how Java is defined to
work) is the result of a specific hack in the definition of the Java type
system. The reasoning is that since anything that implements an interface must
(by definition) be an instance (of a subclass) of java.lang.Object, the type
system knows that all interfaces implicitly "extend" Object. This hack applies
/only/ to the methods of Object.

Highly interesting. This means also that if you program classes e.g. for
drivers, that implements interfaces, and for which you wish to keep
implementation details hidden, you have to be careful with what you put
in your toStgring() method, as it may disclose you.
 
P

Patricia Shanahan

Michael said:
I have defined and Interface

public interface HasChildren{
public int getNumberOfChildren();
public void setNumberOfChildren(int numberOfChildren);

}

and let a class, Student, implement it, like this:

class Student extends Person implements HasChildren{

public String toString(){
//....
}
}

In a test class I have a method:

public void giveBirth(HasChildren hc){

}

hc has no access to other methods defined in Student except the two
methods defined in HasChildren, which I understand.
To my surprise I see that the object hc has access to the method
toString(), even though it is not part of the interface definition.

This seem to be the case also for other methods inherited from class Object

The way I understand, interfaces are not descendent of any
superinterface by default. How does class Object come in there?

Thanks

Michael

Michael

HasChildren is an interface with no direct superinterface,
so the following quote from the JLS applies:

"If an interface has no direct superinterfaces, then the
interface implicitly declares a public abstract member
method m with signature s, return type r, and throws clause
t corresponding to each public instance method m with
signature s, return type r, and throws clause t declared in
Object, unless a method with the same signature, same return
type, and a compatible throws clause is explicitly declared
by the interface."

[http://java.sun.com/docs/books/jls/second_edition/html/interfaces.doc.html#32392]

That is, HasChildren implicitly declares toString.

I think maybe this could have been made more regular by
having an interface, ObjectInterface, with abstract
declarations for those methods. All other interfaces would
extend it, directly or indirectly, just as classes extend
Object. Object would implement it.

Patricia
 
C

Chris Smith

Michael Preminger said:
Highly interesting. This means also that if you program classes e.g. for
drivers, that implements interfaces, and for which you wish to keep
implementation details hidden, you have to be careful with what you put
in your toStgring() method, as it may disclose you.

If the object is a part of an interface to untrusted code, then it's
true that you would not want to expose private information in the return
value of a public method like toString(). That's true of *any* public
method, whether or not the interface declares it, and whether or not the
Object class declares it. If nothing else, reflection can be used to
access the public method and obtain its return value anyway.

So regardless of the details of the type semantics here, don't give out
private information from public methods. Not ever.

--
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
J

John C. Bollinger

Michael said:
I instantiate is as new Student() not new HasChildren().
When a method only knows it is an object of type HasChildren(), I expect
it not to know that it is anything else. (that's one of the fine things
about interfaces). But reading through the rest of the thread I realize
that the methods defined in Object (toString(), hashCode(), equals()
a.s.o) are an exception to this rule.

Rather than calling Object's methods an exception, it is more
satisfactory to me, and might be to you, to ascribe to every method the
certain knowledge that every object it can refer to is an Object. This
is a guarantee provided by the language, whether or not OO purists
approve of it. You are free to not _use_ the methods provided by Object
but not by the interface type declared for your objects, but I don't
think that was your point. None of that changes the facts, of course.


John Bollinger
(e-mail address removed)
 
H

Harish

yes, interfaces are also used to hide "implementation details"...
but they are mainly used to define a contract...as in: methods to be
implemented by all the objects...
also to achive multiple inheritance... and there could be many...
 
C

Chris Uppal

Michael said:
Highly interesting. This means also that if you program classes e.g. for
drivers, that implements interfaces, and for which you wish to keep
implementation details hidden, you have to be careful with what you put
in your toStgring() method, as it may disclose you.

Well that issue would exist even if the semantics of Java interfaces were
cleaner -- the client code could still case the reference to (Object) and
invoke toString() directly.

Interfaces (and other features of Java's type system) are not the right tool to
use for information /concealment/. They do a good job of helping you avoid
unwarranted /coupling/ (rather misleadingly called "information hiding"), but
that's a software engineering concern, not a security issue.

-- chris
 

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,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top