private, nested public, class visible outside package

M

MRe

Hi,

This is probably more a design than programming question, but I
can't find a Java group for that[?]

I have a class that is private within a package, but contains a
nested class that I want to be public outside the package, i.e.
Outside the package, the non-nested class cannot be touched, but the
nested class can. This nested class is accessed by asking another
public class in the package to return it

Is this possible? (More detail below, if that doesn't make sense)

Thank you,
Kind regards,
Eliott

--More detail as promised--

If I have a package-private class called 'DataSet', and nested in
DataSet, a public class 'Stats', and in another file, a package-public
class 'Graph', that could return objects of type DataSet.Stats, I
would want, outside the package to say..

DataSet.Stats stats = graph.getStats();

But this doesn't compile, instead saying that DataSet cannot be
found; which seems simple enough, I can't always do whatever I want!
But is it that simple. Or is there some little [or big] thing I can do
to do what I want to do?

I know I could fix it by factoring the nested Stats part out of
DataSet, but it just feels right nested in DataSet

--Pseudo Java outline of the code--

// A class for displaying a graph
// and some stats in an app
package App
public class GraphPane
{ Graphables.Graph graph;
public void show()
{ Graphables.DataSet.Stats stats;
stats = graph.getStats();
}
}
// A package that embodies graphness
package Graphables;
// A graph with a set of data
public class Graph
{ DataSet dataSet;
public Graphables.DataSet.Stats getStats()
{ return dataSet.getStats();
}
}
// A set of data; in a package-private class
// Don't want the data outside, as only the
// Graph is to know about it
class DataSet
{ Stats stats;
float[] data;
public Graphables.DataSet.Stats getStats()
{ return stats;
}
// Stats (which, in my graphable world) are
// tightly linked with DataSet, and exist
// within data, but is also something that I
// need visible outside the package, because
// the graph doesn't show them
public class Stats
{ float calcMean()
{ float mean = 0;
for(float datum : data)
mean += datum;
return mean /= data.length;
}
}
}

Thanks again; for reading this far :)
 
P

Patricia Shanahan

Peter said:
[...]
I have a class that is private within a package, but contains a
nested class that I want to be public outside the package, i.e.
Outside the package, the non-nested class cannot be touched, but the
nested class can. This nested class is accessed by asking another
public class in the package to return it

Is this possible? (More detail below, if that doesn't make sense)

This isn't possible, not literally.

Even if it were possible, it would not be desirable. It would make the
existence of DataSet, and some of its implementation, visible outside
its package.
However, you can achieve the same effect by defining a public interface
that includes all the public members of the nested class that you want
to have, and then declaring the nested class as implementing that
interface. Then the instance of the nested class can be exposed as an
implementer of the interface, without requiring the code using it to be
able to see the nested class itself.

Strongly agree. Indeed, I typically use an interface for a public method
result, regardless of how the underlying class is implemented. That
leaves me free to nest inside non-public classes, replace with two or
more different classes for different implementation situations etc.
without affecting callers.

Patricia
 
M

MRe

[...]
I have a class that is private within a package, but contains a
nested class that I want to be public outside the package, i.e.
Outside the package, the non-nested class cannot be touched, but the
nested class can. This nested class is accessed by asking another
public class in the package to return it
Is this possible? (More detail below, if that doesn't make sense)

This isn't possible, not literally.

Awh, it isn't, that's a shame :( ..
However, you can achieve the same effect by defining a public interface
that includes all the public members of the nested class that you want to
have, and then declaring the nested class as implementing that interface.
Then the instance of the nested class can be exposed as an implementer of
the interface, without requiring the code using it to be able to see the
nested class itself.

...when suddenly, Bam! Solution! :)

This works great, I like it; fits in really nice.
Thank you very much, (plus for the quick response)

Kind regards,
Eliott
 
M

MRe

Peter said:
[...]
I have a class that is private within a package, but contains a
nested class that I want to be public outside the package, i.e.
Outside the package, the non-nested class cannot be touched, but the
nested class can. This nested class is accessed by asking another
public class in the package to return it
Is this possible? (More detail below, if that doesn't make sense)
This isn't possible, not literally.

Even if it were possible, it would not be desirable. It would make the
existence of DataSet, and some of its implementation, visible outside
its package.

Digable; I kinda figured if Java was complaining about it, there was
something off, but wasn't sure what as I liked the look of it. So long
as there was roughly a similar solution.
Strongly agree. Indeed, I typically use an interface for a public method
result, regardless of how the underlying class is implemented. That
leaves me free to nest inside non-public classes, replace with two or
more different classes for different implementation situations etc.
without affecting callers.

This works good for me. I'm trying my best to be as OO and extensible
as possible, though I seem to spend more time refactoring the code
than programming, but if it gets me a neat solution, I'm happy

Thank you mucho for the response,
Kind regards,
Eliott
 
R

Roedy Green

But this doesn't compile, instead saying that DataSet cannot be
found; which seems simple enough, I can't always do whatever I want!
But is it that simple. Or is there some little [or big] thing I can do
to do what I want to do?

One other possibility, is to have the inner class extend a public
abstract class. You then return that type. This is a variation on
returning an interface.

See http://mindprod.com/jgloss/interfacevsabstract.html
 
M

Mike Schilling

Peter said:
[...]
I have a class that is private within a package, but contains a
nested class that I want to be public outside the package, i.e.
Outside the package, the non-nested class cannot be touched, but
the
nested class can. This nested class is accessed by asking another
public class in the package to return it

Is this possible? (More detail below, if that doesn't make sense)

This isn't possible, not literally.

However, you can achieve the same effect by defining a public
interface that includes all the public members of the nested class
that you want to have, and then declaring the nested class as
implementing that interface. Then the instance of the nested class
can be exposed as an implementer of the interface, without requiring
the code using it to be able to see the nested class itself.


Note that this is a common pattern in Java. Arrays.asList(Object[])
creates a nested class whose implementation details (and even name)
are no one's business, but it's perfectly usable because it implements
List. And this List class has a further nested class to iterate it,
which again is no one's business and again is perfectly usable, this
time because it implements Iterator.
 
T

Tom Anderson

This is probably more a design than programming question, but I can't
find a Java group for that[?]

cljp is fine - design, of this kind, is a part of programming. However,
the other place you could consider would be comp.object.

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

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top