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 -~----------~----~----~----~------~----~------~--~---
