1 2 3 Previous Next 74 Replies Latest reply: Nov 19, 2009 10:27 AM by 807580 RSS

    Class implementing its own inner interface?

    807580
      Hi

      If I try to compile the following I get a "cyclic inheritance involving Data_set" compiler error on line 1:
          public class Data_set implements Data_set.Row
          {
              public interface Row
              {
                  String column(final int a_index);
              }
              public String column(final int a_index)
              {
                  return "something";
              }
              public Row row(final int a_index)
              {
                  return new Row_impl();
              }
              private class Row_impl
                  implements Row
              {
                  public String column(final int a_index)
                  {
                      return "something else";
                  }
              }
          }
      Is there any good logical reason why this should be disallowed, given that the interface is necessarily static and putting it inside the class seems like just a namespace issue that would involve no cyclic dependencies?

      Thanks
      Colin
        • 1. Re: Class implementing its own inner interface?
          807580
          colin_chambers wrote:
          Is there any good logical reason why this should be disallowed, given that the interface is necessarily static and putting it inside the class seems like just a namespace issue that would involve no cyclic dependencies?
          I can't think of one, though I'm not a compiler. Is there any good logical reason why you would ever* want to do this?
          • 2. Re: Class implementing its own inner interface?
            807580
            Motivation is:

            Data_set is a container of Rows. It is a common case in this application that a Data_set contains exactly one Row, and in that case I want to be able to treat the Data_set as a Row (by performing Row operations directly on the Data_set, or by passing the Data_set to something that operates on Rows).

            I realise that this puts an extra precondition on Row operations when applied to a Data_set (namely that the Data_set contains exactly one row), which is slightly naughty but in practice will not cause me a problem as I will only use a Data_set as a Row when the precondition is true.
            • 3. Re: Class implementing its own inner interface?
              795426
              Try making Row a static inner class. In fact, unless you have a very good reason not to do so, all inner classes should be static.
              • 4. Re: Class implementing its own inner interface?
                807580
                None of which seems to be motivation to have Row as a contained interface. A Container is-a Component, and has a list of Components, but you don't see Component being defined with Container, right?

                Also, your design does seem to be faulty. It seems like way too much confusion just to save you from having to get the single row from your data set.
                • 5. Re: Class implementing its own inner interface?
                  807580
                  I don't see the need for Row to be an inner type at all. It's referred to by other types, no? I think you're over-engineering in quite an unnatural way. Just have Row be a top-level interface, there's no big win to what you've done.
                  • 6. Re: Class implementing its own inner interface?
                    807580
                    The Row component here only has meaning with respect to the Data_set container, so I do think that it makes sense to scope the Row name inside Data_set (so that it is referred-to externally as Data_set.Row).

                    Single-row Data_sets are common in this application. I find it useful and not confusing to think of a single-row Data_set as a Row. I would find it extra syntactic clutter to extract the row explicitly in these cases.
                    • 7. Re: Class implementing its own inner interface?
                      807580
                      colin_chambers wrote:
                      The Row component here only has meaning with respect to the Data_set container, so I do think that it makes sense to scope the Row name inside Data_set (so that it is referred-to externally as Data_set.Row).
                      If Row geniunely only has meaning to Data_set, then it shouldn't be public, and Data_set shouldn't be implementing it. Using terms like "it's part of X" without quantifying what that means just leads to ill thought-out models.
                      Single-row Data_sets are common in this application. I find it useful and not confusing to think of a single-row Data_set as a Row.
                      Might be easier in your head, but I guarantee you you'll be writing a lot of extra code as a result.
                      I would find it extra syntactic clutter to extract the row explicitly in these cases.
                      Twenty space-dollars says the exact opposite is true. At every point where Row might be used, you'll have to write twice as much code as if you just dealt with them all uniformly. Look into the Composite design pattern. Might help you here.
                      • 8. Re: Class implementing its own inner interface?
                        JosAH
                        DeltaGeek wrote:
                        Try making Row a static inner class. In fact, unless you have a very good reason not to do so, all inner classes should be static.
                        I fail to see why; care to elaborate?

                        kind regards,

                        Jos
                        • 9. Re: Class implementing its own inner interface?
                          807580
                          colin_chambers wrote:
                          The Row component here only has meaning with respect to the Data_set container, so I do think that it makes sense to scope the Row name inside Data_set
                          I respectfully disagree. Row is much more independent of a set of Rows than a DataSet is from Rows. A row can live on its own, a data set cannot. Your domain modeling is iffy at best.
                          I would find it extra syntactic clutter to extract the row explicitly in these cases.
                          You should never resort to a poor design to avoid "syntactic clutter", and it's quite likely that a proper design will reduce the clutter. My guess is that you've got a bad design through and through, and should consider maybe an inversion of control? Maybe what you're really looking for is a [Visitor pattern|http://en.wikipedia.org/wiki/Visitor_pattern]?
                          public interface RowVisitor {
                             void visitRow(Row row);
                          }
                          
                          public interface RowVisitable {
                             void acceptRowVisitor(RowVisitor visitor);
                          }
                          
                          public class Row extends RowVisitable {
                             public void acceptRowVisitor(RowVisitor visitor) {
                                visitor.visitRow(this);
                             }
                             //...other stuff
                          }
                          
                          public class DataSet implements RowVisitable {
                             private final Collection<RowVisitable> children;
                             public void acceptRowVisitor(RowVisitor visitor) {
                                for ( RowVisitable row : children ) {
                                   row.acceptRowVisitor(visitor);
                                }
                             }
                          }
                          
                          //...
                          DataSet set;
                          RowVisitor printVisitor = new RowVisitor() {
                             public void visitRow(Row row) { 
                                System.out.println(row);
                             }
                          }
                          set.acceptRowVisitor(printVisitor);
                          Another option would be an Iterator pattern.
                          • 10. Re: Class implementing its own inner interface?
                            807580
                            georgemc wrote:
                            Look into the Composite design pattern. Might help you here.
                            Aha! That's the third one that was at the tip of my tongue. Couldn't quite bring it out of secondary storage. Thanks for saving me from a day spent trying to put my finger on that one.
                            • 11. Re: Class implementing its own inner interface?
                              807580
                              endasil wrote:
                              georgemc wrote:
                              Look into the Composite design pattern. Might help you here.
                              Aha! That's the third one that was at the tip of my tongue. Couldn't quite bring it out of secondary storage.
                              Secondary storage is on the tip of your tongue??
                              • 12. Re: Class implementing its own inner interface?
                                807580
                                endasil wrote:
                                georgemc wrote:
                                Look into the Composite design pattern. Might help you here.
                                Aha! That's the third one that was at the tip of my tongue. Couldn't quite bring it out of secondary storage. Thanks for saving me from a day spent trying to put my finger on that one.
                                You were going to try to put your finger on the tip of your tongue, to bring some composite material out of storage?
                                • 13. Re: Class implementing its own inner interface?
                                  807580
                                  karma-9 wrote:
                                  endasil wrote:
                                  georgemc wrote:
                                  Look into the Composite design pattern. Might help you here.
                                  Aha! That's the third one that was at the tip of my tongue. Couldn't quite bring it out of secondary storage. Thanks for saving me from a day spent trying to put my finger on that one.
                                  You were going to try to put your finger on the tip of your tongue, to bring some composite material out of storage?
                                  Whoops, you're right. To bring composite material out of storage, I usually have to put my finger deeper in my mouth than that...
                                  • 14. Re: Class implementing its own inner interface?
                                    807580
                                    By saying Row only has meaning "with respect to" Data_set I meant that its meaning is closely bound up with Data_set. It is not intended to be a general-purpose "row" component. Rows are immutable objects that can only be created by a Data_set, for example, so the only way you can ever get a Row is from a Data_set. However code that uses Data_set can also use Data_set.Row, for example to query the column values of a Row, as in {color:#0000ff}+data_set.row(i).column(j)+{color}. So Row has meaning "to" things other than Data_set.

                                    Certain operations invoked by client code will produce a single-row Data_set. On obtaining such a Data_set you can write {color:#0000ff}+data_set.column(j)+{color} for example to query the "jth" column. This is less code than writing {color:#0000ff}+data_set.row(0).column(j)+{color}.
                                    1 2 3 Previous Next