Separate interface and implemenation problem..

M

MRe

Hi,

I had posted this question already to comp.lang.java.help nested
deep in a thread titled "Decouple Javadoc from Java". I am re-posting
here to give it more visibility.

I am separating interface from implementation (example below) and
have hit on a problem..

The problem is that I need to access private members of the class
I'm in, but through a different object (and this object is of the
interface type (not the implementation) so it does not have access..
the example is probably better able to explain it.

I know this is a bit of a hack (for the reason I'm using it, abusing
the type-system to get a feature Java doesn't provide) but I'm sure
someone must have encountered such a problem and found an eloquent
solution?

Thank you for any help,
Kind regards,
Eliott

~~~

////// TreeNode.java //////
public interface TreeNode
{
public void setParent(TreeNode parentNode);
}

////// TreeNodeImpl.java //////
class TreeNodeImpl implements TreeNode
{
public void setParent(TreeNode parentNode)
{
// problem here: cannot find symbol addChild(TreeNodeImpl)
parentNode.addChild(this);
}
private void addChild(TreeNode childNode) { ... }
}

////// Factory.java //////
public class Factory
{
public static TreeNode createTreeNode()
{
return TreeNodeImpl();
}
}
 
M

MRe

////// TreeNode.java //////
     Right.  There is no reason to believe that a TreeNode
has an addChild() method; the only methods you can be sure
a TreeNode has are setParent() and the things inherited
from Object.  Possible remedies:

     - Include an addChild() method in the TreeNode
       interface definition.

It would be nice if Java allowed protected (or private) modifiers
inside an interface [why doesn't it?]
     - Use `((TreeNodeImpl)parentNode).addChild(this)', and
       pray that you're never called with some other kind
       of TreeNode.

Had thought of this, but I like static type-checking. I would sooner
drop the idea of using an interface [for the reasons I'm using them
here] than implement this.
     I guess you mean `new TreeNodeImpl()'.

Ha, yes. I always forget to type that operator. Why is it even in the
language; when is the class constructor ever referenced, except after
new?

I figured it was a long shot. Thank you for the response Eric,
Kind regards,
Eliott
 
L

Lew

MRe said:
It would be nice if Java allowed protected (or private) modifiers
inside an interface [why doesn't it?]

In addition to what Eric wrote (infra), it would, a), violate the
definition of 'private', and, b), violate the definition of an
interface.

By design, 'private' means "that which the outside world should not
ever know". By design, an interface publishes "exactly what the
outside world must know". They are exact opposite concepts.

Your problem isn't that interfaces don't publish private members.
Your problem is that you want to publish a private member and still
call it 'private'. If you want to publish it, it ain't private!

Eric said:
     Because they'd either (1) be useless, (2) break the access
model, or (3) postpone access errors to run-time: ....

What is the use of complaining that it's there?

Regardless, the 'new' is there to distinguish constructors from
methods.

Every computer language has its little syntactic quirks. If the 'new'
operator weren't there, then you'd have a problem with constructors
and methods looking much alike. Then people would whine, "Why isn't
there something like a 'new' operator to make it clear what's a
constructor and what's a method?"

I have a brilliant idea: why don't you learn the Java language as it
actually is? That is, how about using the power of the language
instead of resisting it and trying to reduce it to your current level
of understanding?

There's no question that Java is not quite a perfect language. There
is, to my knowledge, no perfect computer language. However, perfect
or not, there is a purpose to just about everything in Java.
Unfortunately, or rather fortunately, that purpose does not include
accommodation of every little thing you personally would prefer in a
language.

I have discovered with experience over many computer languages, and in
particular with Java after some years of use, that idioms that seem
verbose or kludgey or complex (generics comes to mind) have a power
and a usefulness that arises from the very verbosity or seeming
kludginess or apparent complexity. It pays to master the language
features as given before whining about them. Only then can you gain a
proper perspective on what can be improved.
 
M

Mike Amling

Lew said:
I have a brilliant idea: why don't you learn the Java language as it
actually is?

Sarcasm doesn't help the situation. I would think that with as much
as you know about Java, you'd realize that it's a lot, and that it takes
many of us a long time to get there.
This is one of very few ad hominem posts I've made.

--Mike Amling
 
L

Lew

Mike Amling said:
   Sarcasm doesn't help the situation. I would think that with as much

Whining that Java shouldn't have a 'new' operator just because one
forgot to use it doesn't help the situation.
as you know about Java, you'd realize that it's a lot, and that it takes
many of us a long time to get there.

It took me a long time to get there, and I am not finished yet.

It would have taken a lot longer if I'd whined about every feature
instead of learning it first.

Once you do know Java well, there are plenty of things to legitimately
whine about. The fact that 'private' members are not public isn't
among them.
   This is one of very few ad hominem posts I've made.

So you don't think it's a valid point that it's important to learn the
language as it is rather than to fight it at every turn?

My point is especially relevant when one is not very familiar with the
language. It is frequently not conducive to good learning to
complain, before one has learned of the thing, that the thing about
which one is learning is flawed.

Most of the time, if one is convinced that the language is in the way
of one's own genius, it's that one has misconstrued the analysis and
is not using the language correctly.
 
M

Mark Space

Patricia said:
I agree that "private" does not make sense for interfaces. However, I
would have uses for default access.

I agree with this. I could also probably come up with uses for
protected methods, and static ones too.

I think that "superpackages" in Java 7 might address some of this, but I
haven't really read enough about them to be sure.

http://jcp.org/en/jsr/detail?id=294
 
M

MRe

Geez Lew, chill out.. I'm not complaining, just questions. About the
private interface: curiosity about the language, to learn; how do I
search for the reason something doesn't exist? About the new operator:
it was mainly rhetorical as a little cover-up of my stupidity of
forgetting to write it in. I could have said, "why is it my brain
always forget to write that?"---I'm sorry I didn't.

I wrote a programming language for my college fourth-year-project and
thought it was kind of neat when I decided it wouldn't have a new
operator, it would be implicit. You should learn my language Lew (it
doesn't even allow comments, no pre-processor), you'll love it.)

Kind regards,
Eliott
 
R

Roedy Green

The problem is that I need to access private members of the class
I'm in, but through a different object (and this object is of the
interface type (not the implementation) so it does not have access..
the example is probably better able to explain it.

You either have to give the members default access or create default
level getters and setters for them. That is what private means, no
snooping both other classes, not even ones in the same package.

see http://mindprod.com/jgloss/privatescope.html
--
Roedy Green Canadian Mind Products
http://mindprod.com

Never discourage anyone... who continually makes progress, no matter how slow.
~ Plato 428 BC died: 348 BC at age: 80
 
L

Lew

You get a lot of that by declaring the interface itself package-
private. The only limitation is that it's an all-or-nothing
proposition. Every method in the interface is accessible only to the
package, or every method is accessible to the public; you can't mix
the two. However, in ten years I've never come up with a need to mix
the two.

Mark said:
I agree with this.  I could also probably come up with uses for
protected methods, and static ones too.

Static methods go against the point of interfaces, since static
methods cannot be inherited. You get everything you need from static
methods in a utility (usually non-instantiable) class anyway.

Protected methods exist to allow implementation inheritance. There is
no real need for interfaces to have them. You can get nearly all of
what you might want from protected interface methods by using a
protected nested interface.

In practice, I have yet to find that interface methods are public to
be a limiting factor.
 
M

MRe

 The problem is that I need to access private members of the class
You either have to give the members default access or create default
level getters and setters for them.  That is what private means, no
snooping both other classes, not even ones in the same package.

Understood, I just thought it was going to be a nice way to separate
interface from implementation. Well, back to reality I go.

Thank you,
Kind regards,
Eliott
 
G

Giovanni Azua

Mark Space said:
I agree with this. I could also probably come up with uses for protected
methods, and static ones too.
static methods in interfaces ... would be like a dream for building a
reusable context-free Singleton Pattern, I spent really time thinking how to
go around this but you can't.

Best regards,
Giovanni
 
M

MRe

The need for "new" in Java is partly a consequence of the decision to
allow the use of the same identifier as the class name and a method name
in the same class:

Wow, you can actually name a method after the class name. I'm
surprised I never knew of that before, it looks very bug prone.

Thank you,
Kind regards,
Eliott
 
M

Mark Space

Steven said:
I wonder if a statically implemented interface would suit better in some
such cases:

// Not real code
class MyClass implements static Runnable {
public static void run() { ... }
}


This is what I meant: some way to enforce a set of static methods on a
class. I like your syntax, although if an interface is only intended to
be used as a "static interface," it might be a good idea to explicitly
declare that fact.

// also not real code
public static interface MyRunnable {
static void run(); // implicitly public
}
 
L

Lew

Steven said:
I've not seen a compelling reason for static methods in an interface yet.

I wonder if a statically implemented interface would suit better in some
such cases:

// Not real code
class MyClass implements static Runnable {
  public static void run() { ... }

}

But that doesn't make Java sense. Static methods don't implement or
override static methods of supertypes, nor can static methods delegate
their action to subtype static methods. In no meaningful sense in
Java, at this time, does a static method in a subtype equate to a
static method in a supertype. Instead, one hides the other. JLS
8.4.8.2:
If a class declares a static method m, then the declaration m is said
to hide any method m', where the signature of m is a subsignature (§8.4..2)
of the signature of m', in the superclasses and superinterfaces of the
class that would otherwise be accessible to code in the class.

The real question to ask is just what benefit one would expect from a
static method in an interface that isn't already available from static
methods in classes. Assuming there is such a benefit, and I can't
think of one, the next question is whether it's worth the distortion
of Java's semantics to make it work.
 
M

Mark Space

Lew said:
Static methods go against the point of interfaces, since static
methods cannot be inherited. You get everything you need from static
methods in a utility (usually non-instantiable) class anyway.


As Steven picked-up on, my intention was to define a kind of interface
for static methods, not replace classes of static methods with
interfaces. I think such an static interface would be useful for
various kinds of factory patterns.



// not real code
public static interface MyFactory {
MyObject makeObject(); // implicitly static and public
}

//...

public class MyObject implements static MyFactory {

public static MyObject makeObject() {
...
}
}

Or something like that...
 
M

Mark Space

Lew said:
The real question to ask is just what benefit one would expect from a
static method in an interface that isn't already available from static
methods in classes. Assuming there is such a benefit, and I can't
think of one, the next question is whether it's worth the distortion
of Java's semantics to make it work.


One disadvantage of static factory methods cited by Bloch is that they
aren't "special" to the compiler or documentation tools, and so can be
difficult for a programmer to spot and use effective. Constructors are
placed specially at the beginning of the Java doc but static methods are
just listed with the rest of the methods.

Another advantage I think would be to allow static methods to implement
a "type" which while not currently "Java-y" I think would be a useful
idiom. Some types are better expressed with static methods, and forcing
them onto classes is vaguely unsatisfying, at least to me.
 
T

Tom Anderson

Lew said:
MRe said:
It would be nice if Java allowed protected (or private) modifiers
inside an interface [why doesn't it?]

In addition to what Eric wrote (infra), it would, a), violate the
definition of 'private', and, b), violate the definition of an
interface.

By design, 'private' means "that which the outside world should not
ever know". By design, an interface publishes "exactly what the
outside world must know". They are exact opposite concepts.
...

I agree that "private" does not make sense for interfaces. However, I
would have uses for default access.

I quite often have a group of classes that present one interface to the
whole of the program, and additional features to the rest of the package
in which they appear. For example, a "get" method might be public, but
the corresponding "set" method package-only. I would love to be able to
define the package-only methods in a package-only interface.

You can get an effect along these lines by having separate public and
package interfaces:

public interface Body {
public Organ getEye();
public Organ getEar();
}

/*package*/ interface BodyInternal extends Body {
public Organ getSpleen();
}

/*package*/ class RobotBody implements BodyInternal {
public Organ getSpleen() {
return new RobotSpleen();
}
// etc
}

As long as you only ever expose Bodies typed as Body, not as any specific
implementing class (for instance, by making those classes package-access,
as i have above), then getSpleen() will never be visible outside the
package. Of course, this does impose quite enormous restrictions on what
you can do with your classes, which might make the whole thing not worth
it.

Another point is that if you have a public method which returns Body, it
has to return Body not BodyInternal, which means either internal users
will have to cast to get a BodyInternal, or you have to have a
package-access shadow method which returns BodyInternal. Both are lame.

tom
 
T

Tom Anderson

I wrote a programming language for my college fourth-year-project and
thought it was kind of neat when I decided it wouldn't have a new
operator, it would be implicit.

Python does this, FWIW. Like:

node = TreeNode()

Although that actually isn't special syntax. It's a method call. Via an
overloaded operator.

The operator in question is (), the call operator. The class 'type', which
is python's answer to Class, overloads it. So, if you have an instance of
type, you can call it as if it was a method - and what the method does is
create a new instance of that type.

This lets you do fun stuff like:

if (shouldCreateList()):
typeToCreate = list
else:
typeToCreate = set
collection = typeToCreate(someElements)

For which there's no really good analogue in java. I think the closest
thing we have would be reflection using a Constructor object, although
what we'd actually do is use a factory.

tom
 

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,774
Messages
2,569,596
Members
45,139
Latest member
JamaalCald
Top