Thanks James.  My broken example was based on this from Bruce Eckel..

http://www.artima.com/weblogs/viewpost.jsp?thread=136394

But it seems to only work for method signatures, not generics.. which
obviously work very differently.

On Jan 30, 1:07 am, James Iry <[email protected]> wrote:
> I don't think what you want to express can be expressed in Java
> because Iterable is invariant - an Iterable<Child> isn't a subtype of
> Iterable<Parent>.  Nor can you write "interface Parent extends
> Iterable<? extends Parent>"
>
> It can be expressed in Scala, but not with Java's standard Iterator/
> Iterable because they aren't covariant.  Scala has a rough equivalent
> in its library that is covariant so this works fine
>   trait Parent extends Iterable[Parent]
>   trait Child extends Parent with Iterable[Child]
>
> It would work in a hypothetical future version of Java with C# 4 style
> variance annotations
>
>   interface Iterator<out T> {
>      public boolean hasNext();
>      publict T next():
>   }
>
>   interface Iterable<out T> {
>      public Iterator<T> iterator();
>   }
>
>   interface Parent implements Iterable<Parent>
>   interface Child extends Parent, Iterable<Child>
>
> This also shows Reinier a use case where immutability isn't necessary
> for covariant type parameters to be useful (an Iterator is not
> immutable).
>
> And to quickly head Reinier off at the pass - it would be trivial to
> write a wrapper to convert this Iterable/Iterator pair into the JCL
> pair so that in order to work with other bits of Java's standard
> library or Java's extended for loop.  So yes, even if the JCL can't be
> "fixed", it's a useful extension to the language.
>
> On Jan 29, 5:44 am, Christian Catchpole <[email protected]>
> wrote:
>
> > Thanks Reinier.  The problem with this is, it requires the calling /
> > working code know the Impl.  And the code which operates on Parents
> > should also operate on Children.  So I never really wanted generic
> > defs on the left hand side.
>
> > These are the first interface definitions I wrote.. Parent will work,
> > but the Child cant extend this way..
> > So I'm looking for something that's functionally identical to this...
>
> > interface Parent extends Iterable<Parent> { }
>
> > interface Child extends Parent, Iterable<Child> { }
>
> > All I really want to do is extend the Iterable type.. The fact that
> > it's it self is irrelevant I guess.
>
> > On Jan 29, 11:27 pm, Reinier Zwitserloot <[email protected]> wrote:
>
> > > Christian: Are you kidding? Of course this code won't work. It's
> > > missing most of the generics! You missed 12 places where you need
> > > generics.
>
> > > I can't fix your code because the snippet just doesn't give any hint
> > > as to what its supposed to do.
>
> > > You need generics parameters almost everywhere with the way you've set
> > > it up - you need them after:
>
> > > class ParentImpl<HERE>
> > > class ChildImpl<HERE>
>
> > > Parent<HERE> parent = new ParentImpl<HERE>();
> > > for ( Parent<HERE> p2 : parent)
>
> > > for (Parent <HERE> p3 : p2)
>
> > > Parent<HERE> p = parent.iterator().next();
>
> > > Child<HERE> child = new ChildImpl<HERE>();
> > > for (Child<HERE> c2 : child)
> > > for (Child<HERE> c3 : c2)
>
> > > Child<HERE> c = child.iterator.next();
>
> > > Possibly this is what you meant? The code below compiles without
> > > errors or warnings.
>
> > > import java.util.*;
>
> > > interface Parent<T extends Parent<T>> extends Iterable<T> {
>
> > > }
>
> > > interface Child<T extends Child<T>> extends Parent<T> {
>
> > > }
>
> > > class ParentImpl implements Parent<ParentImpl> {
> > >     public Iterator<ParentImpl> iterator() {
> > >         List<ParentImpl> list = new ArrayList<ParentImpl>();
> > >         list.add(new ParentImpl());
> > >         return list.iterator();
> > >     }
>
> > > }
>
> > > class ChildImpl implements Child<ChildImpl> {
> > >     public Iterator<ChildImpl> iterator() {
> > >         List<ChildImpl> list = new ArrayList<ChildImpl>();
> > >         list.add(new ChildImpl());
> > >         return list.iterator();
> > >     }
>
> > > }
>
> > > public class Tester {
> > >     public static void main(String[] args) {
> > >         Parent<ParentImpl> parent = new ParentImpl();
> > >         for (Parent<ParentImpl> p2 : parent) {
> > >             System.out.println("> " + p2);
> > >             for (Parent<ParentImpl> p3 : p2) {
> > >                 System.out.println(">> " + p3);
> > >             }
> > >         }
> > >         Parent<ParentImpl> p = parent.iterator().next();
> > >         Child<ChildImpl> child = new ChildImpl();
> > >         for (Child<ChildImpl> c2 : child) {
> > >             System.out.println("> " + c2);
> > >             for (Child<ChildImpl> c3 : c2) {
> > >                 System.out.println(">> " + c3);
> > >             }
> > >         }
> > >         Child<ChildImpl> c = child.iterator().next();
> > >     }
>
> > > }
>
> > > On Jan 29, 7:11 am, Christian Catchpole <[email protected]>
> > > wrote:
>
> > > > My brain hurts.  I love Iterable,  In this example, I'm trying to
> > > > define a Parent interface which iterates a sub-list of it's self
> > > > type.  But I want to be able to inherit to Child and change the
> > > > Iterator to Child.  Which in theory should work because Child is a sub
> > > > class of Parent.  I would expect any code which can operate on Child,
> > > > be able to operate on Parent.
>
> > > > My IDE thinks the "for (Parent p2 : parent)" loops are valid, but they
> > > > don't compile.  I think the problem is I'm not actually implementing
> > > > Parent with any Generic type info.. but I can't find any type
> > > > combinations which work.  And I'd prefer to not have the implementor
> > > > need to pass the type info.
>
> > > > interface Parent<T extends Parent<T>> extends Iterable<T> {
>
> > > > }
>
> > > > interface Child<T extends Child<T>> extends Parent<T> {
>
> > > > }
>
> > > > class ParentImpl implements Parent {
> > > >     public Iterator<Parent> iterator() {
> > > >         List<Parent> list = new ArrayList<Parent>();
> > > >         list.add(new ParentImpl());
> > > >         return list.iterator();
> > > >     }
>
> > > > }
>
> > > > class ChildImpl implements Child {
> > > >     public Iterator<Child> iterator() {
> > > >         List<Child> list = new ArrayList<Child>();
> > > >         list.add(new ChildImpl());
> > > >         return list.iterator();
> > > >     }
>
> > > > }
>
> > > > public class Tester {
> > > >     public static void main(String[] args) {
> > > >         Parent parent = new ParentImpl();
> > > >         for (Parent p2 : parent) {
> > > >             System.out.println("> " + p2);
> > > >             for (Parent p3 : p2) {
> > > >                 System.out.println(">> " + p3);
> > > >             }
> > > >         }
>
> > > >         Parent p = parent.iterator().next();
>
> > > >         Child child = new ChildImpl();
> > > >         for (Child c2 : child) {
> > > >             System.out.println("> " + c2);
> > > >             for (Child c3 : c2) {
> > > >                 System.out.println(">> " + c3);
> > > >             }
> > > >         }
>
> > > >         Child c = child.iterator().next();
> > > >     }
>
> > > > }
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "The 
Java Posse" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/javaposse?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to