Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / December 2007

Tip: Looking for answers? Try searching our database.

Interface Delegation or ??

Thread view: 
Rob McDonald - 15 Dec 2007 05:40 GMT
I am constructing a class hierarchy where I would like to extend a
runtime determined base class.

Lets say I have an Interface, IPoint.

I implement two classes

class Point2D implements IPoint
class Point3D implements IPoint

Then, I want to create a new class, Vertex, which extends from one of
the PointND's.  I don't want to have to implement two Vertex classes
(one for each PointND).

Right now, my solution is to use interface Delegation

class Vertex implements IPoint{
 protected IPoint p;
 Vertex(IPoint p){
   this.p=p;
 }
// Wrap all the IPoint methods to point to this.p
}

Is there any other syntactic mechanism to accomplish this in Java?  Is
this the right way?  Are there some other keywords I should search for
that I'm missing?

TIA,

          Rob
REE9opdZ@gmail.com - 15 Dec 2007 17:23 GMT
> I am constructing a class hierarchy where I would like to extend a
> runtime determined base class.
[quoted text clipped - 28 lines]
>
>            Rob

Hello Rob,

It is hard to see exactly what you are trying to accomplish.  Here are
some thoughts.

(1) Why do you need a separate class for vertices? Why not just use an
IPoint?
(2) Even if you need a separate vertex class, if you can implement all
the vertex methods with only a reference to an IPoint (no references
to Point2D, Point3D, etc) then your method seems sound.
(2) Given that you need a separate vertex class and you need to refer
to , you could probably use generic types:  interface Vertex < P
extends IPoint > { ... }.

I hope this helps.

Emory Merryman
External Concepts Guild
Rob McDonald - 15 Dec 2007 18:03 GMT
On Dec 15, 9:23 am, REE9o...@gmail.com wrote:

> > I am constructing a class hierarchy where I would like to extend a
> > runtime determined base class.
[quoted text clipped - 47 lines]
> Emory Merryman
> External Concepts Guild

This is just a simplified example for discussion.  I will lay out a
bit more for context.

The difference between a IPoint and IVertex is connectivity
information.

A point is just a location in space, whereas a vertex is a member of
some segment.  The Vertex class will keep a list of segments it
belongs to.

At the next level, there will be segments and edges.  A segment is
just an ordered set of vertices.  There will be different
implementations for straight (2-point) and curved (n-point) segments.
There will be geometric methods like segment.length().

Edges will be extended from segments, but edges are used to construct
polygons.  Consequently, edges will have a list of polygons it belongs
to.

At the next level, there will be polygon and face.  A polygon is
purely geometric, a set of edges.  There will be specific
implementations for triangle and quad, and a generic implementation
for an n-gon.  A face is a member of a surface, and will contain a
list of surfaces it belongs to.

I would like this hierarchy to be generic to 2D vs. 3D, straight
segments vs. quadratic vs. cubic vs. spline segments.  Polygons with 3-
edges, 4-edges, and n-gon.  As well as planar vs. curved polygons.

A top level surface should be able to be constructed from mixing &
matching some of these levels (say triangles and quads, not 2D and
3D).  Furthermore, I don't want to have to have a derived class...

surfaceOfTrisWithQuadEdges3D
surfaceOfQuadsWithStraightEdges3D

etc. for every combinatorial possibility.

I hope this helps frame the problem better.  I will look into the use
of generics for this.

           Rob
Lew - 15 Dec 2007 18:30 GMT
> The difference between a IPoint and IVertex is connectivity
> information.
>
> A point is just a location in space, whereas a vertex is a member of
> some segment.  The Vertex class will keep a list of segments it
> belongs to.

It sounds like your solution where Vertex has-a Point is appropriate.

You might be able to abstract the dimensionality of a Point by making it a
parameter or a generic parameter.

Signature

Lew

Rob McDonald - 15 Dec 2007 18:36 GMT
> > The difference between a IPoint and IVertex is connectivity
> > information.
[quoted text clipped - 7 lines]
> You might be able to abstract the dimensionality of a Point by making it a
> parameter or a generic parameter.

Thanks for the tip.

I have certainly been thinking of abstracting the dimensionality of
Point in some manner.

As you probably guessed, I was looking for an OO technique which would
extend throughout the geometry & connectivity hierarchy.  Point/Vertex
was just the simplest example.

            Rob
Lew - 15 Dec 2007 18:52 GMT
Lew wrote:
>> It sounds like your solution where Vertex has-a Point is appropriate.

You mentioned that you delegate "Pointish" methods in Vertex to the internal
Point.  You might be able to expose the Point directly via a getPoint() method
in the Vertex, depending on how dangerous you think that is.

Signature

Lew

Rob McDonald - 15 Dec 2007 20:37 GMT
> Lew wrote:
> >> It sounds like your solution where Vertex has-a Point is appropriate.
>
> You mentioned that you delegate "Pointish" methods in Vertex to the internal
> Point.  You might be able to expose the Point directly via a getPoint() method
> in the Vertex, depending on how dangerous you think that is.

I would prefer to be able to treat Vertex with is-a semantics rather
than an explicit getPoint() has-a approach.

However, there may someday be the need for runtime type checking of
the underlying Point.  I was thinking of implementing a
getPointClass() method in Vertex which would simply...

public class Vertex implements IPoint{
 IPoint p;
 public Vertex(IPoint p){
   this.p = p;
 }

 public Class getPointClass(){
   return p.getClass();
 }

 // All the wrappers around p to implement IPoint.
}

Of course, right now I am very unsure of how generics come into this.
The standard

public final Class <? extends Object> getClass()

gives me the willies...

I guess you would use it something like this?

Class c <? extends IPoint> = vtx.getPointClass();

      Rob
Lew - 15 Dec 2007 20:50 GMT
> However, there may someday be the need for runtime type checking of
> the underlying Point.  I was thinking of implementing a
[quoted text clipped - 9 lines]
>     return p.getClass();
>   }

When you start branching based on explicit knowledge of a class, it's time to
rethink your object model, as it is almost always wrong in that case.

> I would prefer to be able to treat Vertex with is-a semantics rather
> than an explicit getPoint() has-a approach.

Then generics are likely your answer, as REE9opdZ@gmail.com suggested.

Signature

Lew

Rob McDonald - 15 Dec 2007 21:12 GMT
> When you start branching based on explicit knowledge of a class, it's time to
> rethink your object model, as it is almost always wrong in that case.

You very well may be right on this point.

> > I would prefer to be able to treat Vertex with is-a semantics rather
> > than an explicit getPoint() has-a approach.
>
> Then generics are likely your answer, as REE9o...@gmail.com suggested.

How can I use generics to do this?  I want to extend from an arbitrary
base class (known to implement some interface).

My experience with generics is very much in the spirit of
Collections<T>.  Which really doesn't seem to apply here.

I guess I'll go hit the books some more, but I thought this was the
question I asked in the first place.

         Rob
External Concepts Guild - 18 Dec 2007 18:51 GMT
> > Then generics are likely your answer, as REE9o...@gmail.com suggested.
>
[quoted text clipped - 8 lines]
>
>           Rob

Below is sample code.  This code works for one dimensional space
(points are BigDecimals).  You can extend it to other dimensions by
(1) implementing some class to represent the higher dimension points
and (2) implementing some DistanceMetric class that works on the new
Point class.  If you do 1 and 2 correctly, you should be able to use
the ListSegmentFactory without any further modifications.

I hope this helps.

Emory Merryman
External Concepts Guild

/**
* Useful for making things.
**/
interface Factory < R , P , E extends java . lang . Exception >
{
   public abstract R make ( final P p ) throws E ;
}

/**
* Can be used to calculate the distance between two Points
**/
interface DistanceMetric < P , R extends java . lang . Comparable < R

{
   public abstract R distance ( final P p1 , final P p2 ) ;
}

/**
* Calculates the euclidean distance between two one dimension points
* represented by java.math.BigDecimal.
**/
final class Distance1D implements DistanceMetric < java . math .
BigDecimal , java . math . BigDecimal >
{
   public final java . math . BigDecimal distance ( final java .
math . BigDecimal p1 , final java . math . BigDecimal p2 )
    {
       final java . math . BigDecimal difference = p1 . subtract
( p2 ) ;
       final java . math . BigDecimal distance = difference . abs ( ) ;
       return ( distance ) ;
    }
}

/**
* Segments have length.
**/
interface Segment < P , R extends java . lang . Comparable < R > >
{
   public abstract R length ( ) ;
}

/**
* Makes a Segment based on the specified ordered list of points.
* Uses the specified distance metric to calculate the length.
**/
final class ListSegmentFactory < P > implements Factory < Segment <
P , java . math . BigDecimal > , java . util . List < P > , java .
lang . RuntimeException >
{
   ListSegmentFactory ( final DistanceMetric < P , java . math .
BigDecimal > dm )
    {
       super ( ) ;
       this . dm = dm ;
    }

   private DistanceMetric < P , java . math . BigDecimal > dm ;

   public final Segment < P , java . math . BigDecimal > make ( final
java . util . List < P > points )
   {
    final Segment < P , java . math . BigDecimal > segment = new Segment
< P , java . math . BigDecimal > ( )
       {
        public final java . math . BigDecimal length ( )
        {
           java . math . BigDecimal length = java . math . BigDecimal .
ZERO ;
           for ( int i = 1 ; i < points . size ( ) ; i ++ )
            {
               final P p1 = points . get ( i - 1 ) ;
               final P p2 = points . get ( i ) ;
               final java . math . BigDecimal distance = dm . distance ( p1 ,
p2 ) ;
               length = length . add ( distance ) ;
            }
           return ( length ) ;
        }
       } ;
    return ( segment ) ;
   }
}
Lew - 21 Dec 2007 16:12 GMT
> Below is sample code.  This code works for one dimensional space
> (points are BigDecimals).  You can extend it to other dimensions by
[quoted text clipped - 4 lines]
>
> I hope this helps.

It's a great example, but the embedded TABs in the listing push some of the
source text way off to the right, and hurt readability.  I suggest indentation
using spaces only, and keep it fairly narrow; an indent of between two to four
spaces suffices for Usenet.

> /**
>  * Useful for making things.
[quoted text clipped - 11 lines]
>     public abstract R distance ( final P p1 , final P p2 ) ;
> }

> /**
>  * Segments have length.
[quoted text clipped - 3 lines]
>     public abstract R length ( ) ;
> }

It doesn't look like interface Segment uses the P parameter at all.  Perhaps
it's safe to drop it?

To other readers: take note that these interfaces have package-private access.
 This automatically restricts all use of these interfaces to the package (no
need for messy access decorations on the individual methods - Java is
convenient this way.)

Signature

Lew

tam@milkyway.gsfc.nasa.gov - 21 Dec 2007 17:32 GMT
> > /**
> >  * Useful for making things.
[quoted text clipped - 26 lines]
> --
> Lew

Not entirely.  As we discussed in another thread,  declaring a public
class which implements these interfaces, means all of the interface
methods must also be visible to the public though the existence of the
interfaces themselves may be hidden.  You can explicitly hide the
methods using delegation but then you will need to be aware of this
implementation whenever you do want to use the interfaces.  A public
class can never explicitly implement an interface and simultaneously
hide the associated methods.

  Regards,
  Tom McGlynn
Lew - 22 Dec 2007 01:03 GMT
>>> /**
>>>  * Useful for making things.
[quoted text clipped - 34 lines]
> class can never explicitly implement an interface and simultaneously
> hide the associated methods.

The interface /per se/ is hidden to the public, so cannot be used as a
supertype or otherwise directly accessed outside the package.

It is true that public methods declared to implement the interface in a public
class will be visible to the outside, but that clearly would be a deliberate
decision by the implementor.  It would also argue for making the interface
public.  If the interface is package-private, it is usually because it is used
only in a package-private context.

It remains true that all uses of the package-private interface will "entirely"
be package-local.  There's no way around that.  It may well be that other
classes exposes implementing methods to the public; that doesn't change the
truth of the assertion that the interface itself remains hidden.

Signature

Lew

tam@milkyway.gsfc.nasa.gov - 22 Dec 2007 15:42 GMT
> t...@milkyway.gsfc.nasa.gov wrote:

...

> > Not entirely.  As we discussed in another thread,  declaring a public
> > class which implements these interfaces, means all of the interface
> > methods must also be visible to the public though the existence of the
> > interfaces themselves may be hidden.
...

> The interface /per se/ is hidden to the public, so cannot be used as a
> supertype or otherwise directly accessed outside the package.
>
> It is true that public methods declared to implement the interface in a public
> class will be visible to the outside, but that clearly would be a deliberate
> decision by the implementor.
...
> Lew

I was responding to these words a couple of messages upstream...

--To other readers: take note that these interfaces have package-
private access.
--This automatically restricts all use of these interfaces to the
package (
>>>> no need for messy access decorations on the individual methods <<<
-- Java is convenient this way.)

The "no need..." might suggest to a reader that the methods were in
fact hidden by making the interface package protected and that's what
I tried to clarify.

Also, when you say:
>  It is true that public methods declared to implement the interface in a public
>  class will be visible to the outside, but that clearly would be a deliberate
>  decision by the implementor.
I'm not clear what you're getting at.  Certainly a coder explicitly
chooses to include an interface, but once they do they have no choice
about implementing the methods as public.  When implementing a package
level interface in a public class a code must expose the package
methods.

Typical interfaces consist of three elements two of which can be
hidden from the public (absent reflection) in a package level
interface:

  The interface type
  Interface-defined constants [I haven't checked this but I believe
it to be so]

and one which must be made visible to the public

  The methods

   Regards,
   Tom McGlynn
Lew - 22 Dec 2007 16:36 GMT
> I'm not clear what you're getting at.  Certainly a coder explicitly
> chooses to include an interface, but once they do they have no choice
> about implementing the methods as public.  When implementing a package
> level interface in a public class a code must expose the package
> methods.

Well, there's your mistake right there.  You're not supposed to implement
package-level interfaces in public classes.  Package-level interfaces are for
package-level classes, otherwise for public classes use a public interface.

If you want to lock down certain parts of the implementation, which is what
methods at less than public access are for, use an abstract class as the
parent and put those parts there.

Interfaces do not exist for the purpose of specifying implementation, thus
they do not support method-level access less than public.  Period.  That's
their whole point.  If you want an interface to be used only within the
package, you declare the whole interface package-private, and use it only for
package-private classes.

The point of an interface is that it makes a supertype with all method
signatures defined, but *not* implementation.  Having it support
less-than-public methods would defeat its purpose.

Again, if your interface is not public, then neither should its implementors
be.  That's the Java idiom.  It's abstract classes that you want, in order to
nail down parts of the implementation.

Signature

Lew

tam@milkyway.gsfc.nasa.gov - 23 Dec 2007 17:57 GMT
...
> Well, there's your mistake right there.  You're not supposed to implement
> package-level interfaces in public classes.  Package-level interfaces are for
[quoted text clipped - 10 lines]
> package-private classes.
> Lew

Hmmm...  I don't think I consider the visibility of a method part of
its implementation -- any more than say its return type.

Regardless, I don't think the visibility of the interface makes much
practical difference if the interface is only implemented in package
level code.

E.g., let's consider that we've adopted your rule and package visible
interfaces are implemented only in package visible classes.  Clearly
the interface is not visible to the public, nor can any implementation
of any method in the interface be accessed outside the package.

Now let's make the interface public.  We still want to restrict use
the interface to one package, but we're exploring what making it
public does. So what happens?

The clearest change is that external(to the package) users can now
access the constants defined in the interface.  That's a real change
and its certainly useful to restrict visibility of constants in some
cases, but our dicussion heretofore has focussed on how methods are
affected.  What happens there?

Public users still cannot directly access the implementation of any of
the methods, because the class protections for each of the
implementing classes are still set to package level.

Ah, but they can now create their own implementation of the interface
and pass it in to some public method that takes the interface as an
input and thus get access to something they weren't able to get to
before...   I.e.,

   package pack;
   public class SomeClass {
       public void someMethod(HiddenInterface x) {...}
   }
   ...
   package otherpack;
   public class NewClass implements HiddenInterface {
        void crackingMethod() {
             someMethod(this);
        }
   }

where HiddenInterface is the interface that we just made public.

Here crackingMethod is able to inject an instance of the new user
class and clearly might have access where it didn't before.  So this
seems new...

That's right, but why was there a public method in a public class that
used a type that didn't wasn't supposed to be available to the
public?  The only legitimate reason I might see is that  'someMethod'
is itself defined in an interface so it needed to be public.   But if
it's in an interface that uses HiddenInterface, then presumably this
second interface is also only supposed to be used within the package
so by hypothesis we shouldn't be implementing it in a public class.

So what did the package level protection get us:  It hid constants and
it's probably useful as a bit of documentation:  it can indicate we
should limit visibility of certain classes and methods, but at best it
should act as kind of backup, cleaning up if we make errors in some of
our visibility specifications for methods in public classes.

That said, I'm not sure I agree with your first statement above...
Users should feel free to implement package level interfaces in public
classes.  There may be many cases where that's fine.  All I've ever
said is that if they do so, they need to recognize that the
implementation of the methods  of the interface must be visible to the
public regardless of the visibility of the interface itself.

I can see reasonable cases for any combination of public and package
classes implementing public and package interfaces, but the
interactions of the visibilities of the classes, interfaces and
methods are rather subtle.
And all this is before we consider how inheritance might affect all of
this!

  Regards,
  Tom McGlynn
Lew - 23 Dec 2007 21:00 GMT
> Hmmm...  I don't think I consider the visibility of a method part of
> its implementation -- any more than say its return type.

Interfaces don't have implementation.

> Regardless, I don't think the visibility of the interface makes much
> practical difference if the interface is only implemented in package
> level code.

It makes a difference to the visibility of the interface type, which is the
reason one mucks with visibility.

> E.g., let's consider that we've adopted your rule and package visible
> interfaces are implemented only in package visible classes.  Clearly
> the interface is not visible to the public, nor can any implementation
> of any method in the interface be accessed outside the package.

So far, so good.

> Now let's make the interface public.  We still want to restrict use
> the interface to one package, but we're exploring what making it
> public does. So what happens?

There's your problem right there.  If you want to restrict use of the
interface to just the package, why are you making it public?  That makes no sense.

> The clearest change is that external(to the package) users can now
> access the constants defined in the interface.  That's a real change

You should never define constants in an interface.  That antipattern is an
Item in Joshua Bloch's /Effective Java/.  Interfaces are there to define
contract, not implementation.  Putting constants in an interface is an abuse.

> and its certainly useful to restrict visibility of constants in some
> cases, but our dicussion heretofore has focussed on how methods are
[quoted text clipped - 3 lines]
> the methods, because the class protections for each of the
> implementing classes are still set to package level.

Because these classes, *by design*, are not intended for public use.

> Ah, but they can now create their own implementation of the interface
> and pass it in to some public method that takes the interface as an
> input and thus get access to something they weren't able to get to
> before...   I.e.,

No previous implementation of the interface can have been passed to a public
method in a public class, since none of the type or its subtypes were publicly
visible.  Your scenario cannot happen.

>     package pack;
>     public class SomeClass {
>         public void someMethod(HiddenInterface x) {...}
>     }

When the 'HiddenInterface' had package-private access, and was not in package
'pack', this method would have raised a compiler error.

>     ...
>     package otherpack;
[quoted text clipped - 8 lines]
> class and clearly might have access where it didn't before.  So this
> seems new...

To what?  Access to what?  All the previous classes had package-private
access.  Calling the method 'crackingMethod()' doesn't make it magically able
to crack anything.

Furthermore, why was the interface promoted to public access?  Surely such a
decision is weighed against the cost of changes.  But worrying about cracking
into a package-private implementation isn't one of them.  In fact, it's one of
the most common idioms in Java to have package-private or private
implementations of public interfaces.  What you tout as a disadvantage is
actually one of the great strengths of the language.

> That's right, but why was there a public method in a public class that
> used a type that didn't wasn't supposed to be available to the
[quoted text clipped - 3 lines]
> second interface is also only supposed to be used within the package
> so by hypothesis we shouldn't be implementing it in a public class.

Nor could any public method of a public class from a different package make
use of a non-public interface.

> So what did the package level protection get us:  It hid constants and

Constants that should never be defined in an interface in the first place.

> it's probably useful as a bit of documentation:  it can indicate we
> should limit visibility of certain classes and methods, but at best it
> should act as kind of backup, cleaning up if we make errors in some of
> our visibility specifications for methods in public classes.

It isn't "documentation", it's a fundamental decision about the use of a type
whether to make it public or package-private.

> That said, I'm not sure I agree with your first statement above...
> Users should feel free to implement package level interfaces in public

No, they shouldn't.  If it's in a different package, you get a compiler error.
 The reason to make something package-private is to restrict its visibility.
 If you don't restrict the visibility, then you have no reason to declare it
with restricted visibility.  Your suggestion contradicts the very point of
declaring restricted visibility.

> classes.  There may be many cases where that's fine.  All I've ever
> said is that if they do so, they need to recognize that the
> implementation of the methods  of the interface must be visible to the
> public regardless of the visibility of the interface itself.

Programmers need to be aware of the implications of the visibility rules in
their chosen language, yes.  If you choose to implement a package-private
interface in a public class, that's fine, but users of the public class will
not have access to the supertype.  To them, the methods will just look like
regular, non-contracted methods, just as if there were no interface involved.
 Indeed, one must presume that is intentional, else why do such a thing?

> I can see reasonable cases for any combination of public and package
> classes implementing public and package interfaces, but the
> interactions of the visibilities of the classes, interfaces and
> methods are rather subtle.

The actual interactions are precisely specified for Java.

> And all this is before we consider how inheritance might affect all of
> this!

Interfaces exist for the whole purpose of inheritance.  This is not "before we
consider" inheritance; in fact, my advice all along in this and the other
thread was based on the notion of inheritance.  It's fundamental to the entire
conversation so far.  It is the entire point.  It is the heart of the matter,
and has been from the start.  Not only are we not "before" such consideration,
we are steeped in it, drowning in it.  It is the only thing under consideration.

Not dealing with the notion of inheritance in talking of package-private
visibility for interfaces and abstract classes (see upthread) invalidates any
possibility of understanding the issues involved, since the issues involved
*are inheritance issues*.

From the start, intrinsically.

Signature

Lew

Lew - 23 Dec 2007 21:38 GMT
tam@milkyway.gsfc.nasa.gov wrote:
>> Ah, but they can now create their own implementation of the interface
>> and pass it in to some public method that takes the interface as an
>> input and thus get access to something they weren't able to get to
>> before...   I.e.,

> No previous implementation of the interface can have been passed to a
> public method in a public class, since none of the type or its subtypes
> were publicly visible.  Your scenario cannot happen.
> ...
> The actual interactions are precisely specified for Java.

If the public class is in the same package as the package-private interface,
it can get away with exporting the interface type via a public method.

While technically legal, it does raise a warning in my IDE.  (NetBeans, as it
happens, but I'm pretty sure Eclipse supports this warning also.)

  "Exporting non-public type through public API"

This pathological example does just that in the methods that set and get an
'InnerFace' instance.  It makes 'Fimpl' a little difficult to use from outside
the package; the client code has to treat the signatures as though they used
'Object' instead of 'InnerFace' and they don't have access to the supertype,
specifically not to its methods.  (Not through the supertype reference, at least.)

While this usage is barely legal, the best advice is not to do it.  Don't
expose restricted visibility types to wider examination.  If you make a type
package-private, it's for a reason.  It's a type.

public class Fimpl implements Runnable
{
    /** Keep the interface on the down-low.
     */
    /* p-p */ static class NestedFimpl implements InnerFace
    {
        @Override
        public void foo()
        {
            System.out.println( "NestedFimpl.foo()" );
        }
    }

    private volatile InnerFace face;

    /** No-arg constructor.
     */
    public Fimpl()
    {
        this( null );
    }

    /* p-p */ Fimpl( InnerFace f )
    {
        face = (f == null? new NestedFimpl() : f);
    }

    /* p-p */ void setFace( InnerFace f )
    {
        face = (f == null? new NestedFimpl() : f);
    }

    /* p-p */ InnerFace getFace()
    {
        return face;
    }

    /** Delegate an action to <code>foo()</code>.
     */
    @Override
    public void run()
    {
        face.foo();
    }

    /** Expose the package-private interface to the whole world.
     * @param f non-visible type, pass an <code>Object</code>.
     */
    public void setInnerFace( InnerFace f )
    {
        setFace( f );
    }

    /** Expose the package-private interface to the whole world.
     * @return non-visible type, treat as <code>Object</code>.
     */
    public InnerFace getInnerFace()
    {
        return getFace();
    }
}

Signature

Lew

Codedigestion - 23 Dec 2007 23:40 GMT
> t...@milkyway.gsfc.nasa.gov wrote:
> >> Ah, but they can now create their own implementation of the interface
[quoted text clipped - 90 lines]
> --
> Lew

Peace Rob,

I'm not exactly sure what you're trying to do, but as I can ascertain
from your first post, it seems that you're trying to use a Design
Pattern called the "Strategy Pattern".  I think this is what you're
looking for, perhaps:

-----------------------------

public interface IPoint {
   public void dosomething();
}

-----------------------------

public class Point2D implements IPoint {
   public void doSomething() {
      System.out.println("I'm 2D.")
   }
}

-----------------------------

public class Point3D implements IPoint {
   public void doSomething() {
      System.out.println("I'm 3D.")
   }
}

-----------------------------

public abstract class Vertex {
   IPoint iPoint;

   public Vertex(){
   }

   public void pleaseDoSomething() {
       iPoint.doSomething();
   }

}

----------------------------

public 2DVertex extends Vertex{
 doSomething = new Point2D();
}

----------------------------

public 3DVertex extends Vertex{
 doSomething = new Point3D();
}

----------------------------

I don't know if this code will even work.  Quite frankly, I'm new to
this myself, but I think this may be what you're looking for;  The
Strategy Pattern.  Especially if you want to program to 'composition'
instead of 'implementation'.  I've found out about all of this from
Head First Design Patterns:
http://www.amazon.com/gp/product/0596007124?ie=UTF8&tag=myprfothusst1-20&linkCod
e=xm2&camp=1789&creativeASIN=0596007124


Let me know how this works for ya', would ya'?  Well this stuff makes
a lot more sense in the book.  Perhaps I've done a poor job of
explaining it.  I think if you do a google search for "Strategy Design
Patterns" you may get better examples, God willing.

God Bless,

shree
Codedigestion - 23 Dec 2007 23:41 GMT
> > t...@milkyway.gsfc.nasa.gov wrote:
> > >> Ah, but they can now create their own implementation of the interface
[quoted text clipped - 167 lines]
>
> shree

package wikipedia.patterns.strategy;

// MainApp test application
class MainApp {

 public static void main(String[] args) {
   Context context;

   // Three contexts following different strategies
   context = new Context(new ConcreteStrategyA());
   context.execute();

   context = new Context(new ConcreteStrategyB());
   context.execute();

   context = new Context(new ConcreteStrategyC());
   context.execute();
 }
}
 // The classes that implement a concrete strategy should implement
this
 // The context class uses this to call the concrete strategy
 interface IStrategy {
   void execute();
 }

 // Implements the algorithm using the strategy interface
 class ConcreteStrategyA implements IStrategy {
   public void execute() {
     System.out.println( "Called ConcreteStrategyA.execute()" );
   }
 }

 class ConcreteStrategyB implements IStrategy  {
   public void execute() {
     System.out.println( "Called ConcreteStrategyB.execute()" );
   }
 }

 class ConcreteStrategyC implements IStrategy {
   public void execute() {
     System.out.println( "Called ConcreteStrategyC.execute()" );
   }
 }

 // Configured with a ConcreteStrategy object and maintains a
reference to a Strategy object
 class Context {
   IStrategy strategy;

   // Constructor
   public Context(IStrategy strategy) {
     this.strategy = strategy;
   }

   public void execute() {
     strategy.execute();
   }
 }

---------------------------------------------
http://en.wikipedia.org/wiki/Strategy_pattern
Rob McDonald - 27 Dec 2007 04:39 GMT
> Peace Rob,
>
[quoted text clipped - 72 lines]
>
> shree

Shree,

Thanks for the help and the thoughts.  I think you are close to
demonstrating the interface delegation concept I mentioned, but there
is one hitch.

I don't want to have a separate Vertex class for 2D and 3D.  That way,
I can have 2D and 3D Point classes (and maybe 1D, and ND) and then
just make a Vertex with whatever Point it needs.  Ideally, the Vertex
implementation will be very simple.

Normally in a class hierarchy, you start with simple, abstract things
and build to more specific and complex implementations.  In that
pattern, you naturally end up with many implementations at your final
level of abstraction.  Swing provides an example of this...  (from the
Java API docs)

java.lang.Object
 extended by java.awt.Component
     extended by java.awt.Container
         extended by javax.swing.JComponent
             extended by javax.swing.AbstractButton
                 extended by javax.swing.JToggleButton
                     extended by javax.swing.JRadioButton

A JRadioButton is-a lot of different things.  As you progress up the
chain, each level implements certain methods/interfaces for you.  At
the final level of the chain, there are a very large number of classes
which are JComponent's.

You can visualize this as a tree, fanning out to have many branches at
the top.

In my situation, things are a bit different (first, it isn't nearly as
complex as Swing).  In my structure, the underlying class has more
options/complexity than the top level.  Instead of a tree, we have a
pyramid or a root system, with lots of things at the bottom combining
to one thing at the top.

So, what I would like, is the ability to have a variety of
implementations at the lower level (Point), but then bring them all
together under a single Vertex implementation.  To me, it is very
important to have only one Vertex implementation.

Your example can achieve this by using the interface delegation
construct I mentioned earlier.  Basically, change your Vertex
constructor to accept a Point as its argument. The program will still
have to instantiate the correct Point2D or Point3D, and then pass it
to the Vertex at the time of instantiation.

Hopefully this all makes more sense when applied to Segment/Edge, Poly/
Face etc.

          Rob
Codedigestion - 27 Dec 2007 13:32 GMT
> > Peace Rob,
>
[quoted text clipped - 127 lines]
>
>            Rob

Peace Rob,

As I'm new to all of this, I was able to understand more from you than
from myself.  :)  It seems as if you're looking to build some sorta'
abstraction layer with a single entry point to access a huge hierarchy
of capability limited down to a specific functionality.  Perhaps, it
would be one of the other design patterns.  I've only been able to
read 3 patterns thus far.  Will keep a lookout for you, sir...

God Bless,

shree
tam@milkyway.gsfc.nasa.gov - 24 Dec 2007 03:35 GMT
My suspicion is that Lew and I are at the point where we're talking
past each other so I'll leave it here.

However in closing I would like to correct the idea I put forward that
there would not be a 'legitimate' use for code like:

   package pack;
   interface HiddenInterface {...}

   public class SomeClass {
       public void someMethod(HiddenInterface x) {...}
   }

I'd suggested that this was legal but couldn't see any reason for it,
while Lew noted that NetBeans cautions against it and also suggested
that it wasn't  a good idea.  Despite our agreement, I now suspect we
were both wrong. Such a usage might be perfectly appropriate if we add
some additional interfaces to the package, e.g.,

   final public interface Visible1 extends HiddenInterface {...}
   final public interface Visible2 extends HiddenInterface {...}

Then for example we might have:

   package otherpack;
   public class AnotherClass implements Visible1 {
      ...
      pack.SomeClass xxx = ...
      xxx.someMethod(this);
      ...
   }

Restricting the base interface to package visibility means that all of
the public interfaces must be declared in the pack package (assuming
we make all the derived interfaces final).  So that package still can
limit the valid interfaces.  We need to use the base interface in the
method signature to assure that we can handle all of the sub-
interfaces.

I could imagine something like this being needed in sophisticated
factory patterns though I've never had requirements for such - I very
rarely extend interfaces at all.  It seems reasonably straightforward
but I've not explicitly checked that it's legal.  Since NetBeans looks
at the entire project I'd expect it to notice the additional
interfaces and give up it's warning, but again I haven't checked.

While this is another reason one might use package interfaces, it does
not materially affect my earlier discussion of the extent to which
package level interfaces and their contents are visible to the public.

Merry Christmas to all!
Tom McGlynn
Rob McDonald - 27 Dec 2007 00:02 GMT
OP back online after being away for a few days (also got lost in a sea
of spam for a while there).

All these posts will take me a bit to digest, but thanks to all who
have kept it active.

I'm sure these answers will spawn more questions.

        Rob
Daniel Pitts - 18 Dec 2007 19:56 GMT
> I am constructing a class hierarchy where I would like to extend a
> runtime determined base class.
[quoted text clipped - 28 lines]
>
>            Rob

There is no clean way to extend at runtime. While a Vertex may seem
like a Point to you, its really not a Point.  A Vertex has a location,
and has related Edges, where a Point simply has a Location.  Perhaps
you really want a Location2d and Location3d, and then a class Point<L
extends Location>, and class Vertex<L extends Location>

If you think about abstracting the concept of a location from the
concept of a point/vertex, you simply this model a bit.
Mark Space - 19 Dec 2007 22:13 GMT
> There is no clean way to extend at runtime. While a Vertex may seem
> like a Point to you, its really not a Point.  A Vertex has a location,
[quoted text clipped - 4 lines]
> If you think about abstracting the concept of a location from the
> concept of a point/vertex, you simply this model a bit.

I was sort of thinking the same.  A point is a fairly lightweight
concept and trying to extend it to a class that add so little to the
point might be a misfeature.

I think the OP should consider skipping a Vertex class and going
straight for Strips, Meshes, Fans and Polygons.  These would naturally
have lists of Points (has-a) and should probably implement their own
methods for finding edges and adjacent points, because they'll each need
slightly different algorithms for best efficiency.

Points might even be implemented internally just by 2d arrays.
Operations on points could just be static methods.  Don't forget that
while fairly small, there is overhead associated with method calls when
inheritance might be involved.
Daniel Pitts - 20 Dec 2007 16:24 GMT
>> There is no clean way to extend at runtime. While a Vertex may seem
>> like a Point to you, its really not a Point.  A Vertex has a location,
[quoted text clipped - 19 lines]
> while fairly small, there is overhead associated with method calls when
> inheritance might be involved.
Now you've gone a little to far in the opposite direction. It is
important to avoid primitive obsession in program design.  I think a
Vertex class is useful, as it can have a list of Edge objects that
connect via itself.  Unless you need a specialized algorithm for some
reason, use the cleanest abstract approach.

Signature

Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/>

Rob McDonald - 27 Dec 2007 04:18 GMT
> There is no clean way to extend at runtime. While a Vertex may seem
> like a Point to you, its really not a Point.  A Vertex has a location,
[quoted text clipped - 4 lines]
> If you think about abstracting the concept of a location from the
> concept of a point/vertex, you simply this model a bit.

At this level, I fail to see the difference between a Location and a
Point; however, I am more than willing to explore the ideas.

Maybe it would've been better if I had given an example a little
higher up the food chain.  The segment/edge relationship is a bit more
rich than the point/vertex situation.  As I discussed in an earlier
post, I am interested in exploring this concept throughout the
hierarchy.

My general structure concept is borrowed from GTS gts.sourceforge.net/
reference/book1.html .  GTS is written in ANSI C, but is brutally
object oriented in the style of GTK.  Although my structure is
patterned off of GTS, I hope to build in a greater level of generality/
abstraction.

Back to the segment/edge relationship.  To me, Segments are finite
length lines (or curves) in space.  All Segments will have a starting
and ending vertex.  Some Segments will have intermediate vertices.
The implementation of Segment should not care what kind of Vertex is
used (of course, this is a has-a relationship).

The obvious Segment candidates are Linear, Quadratic, and Spline.
Others are of course possible.  Furthermore, there are lots of ways to
implement each of these types.  For example, the quadratic segment
could store the three points individually, in an array, or in a list.
It could even store the end points and derivative information instead
of a 3rd point.

Edges are used to build up polygons.  A Poly is essentially a list of
Edges.  Each Edge contains a list of Polys it is a part of.  In a
topologically correct closed surface, each Edge should be a part of
two Polys.

I want Edge to have an is-a relationship to Segment.  However, I
expect the Edge implementation to be rather simple, and it should be
the same no matter the underlying Segment.

      Rob
Roedy Green - 21 Dec 2007 19:41 GMT
On Fri, 14 Dec 2007 21:40:55 -0800 (PST), Rob McDonald
<rob.a.mcdonald@gmail.com> wrote, quoted or indirectly quoted someone
who said :

>Is there any other syntactic mechanism to accomplish this in Java?

I thing delegation is the way to fly.  Otherwise you would have to
implement both interfaces, using dummy implementations that threw
UnsupportedOperationException exceptions.
Signature

Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com



Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2009 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.