接口的实现必须实现其内部类构建器接口。怎么做?

时间:2013-10-28 11:32:49

标签: java generics interface inner-classes builder

我有一个有趣的问题。

我已经创建了一个界面;我们的想法是,实现此接口的类也必须实现TimeRangeBuilder

import java.util.Date;

public interface TimeRange<T> extends Comparable<T> {   

    public static interface TimeRangeBuilder<T> {
        public TimeRangeBuilder<T> startDate(Date startDate);
        public TimeRangeBuilder<T> endDate(Date endDate);
        public T build();
    }

    public Date getStartDate();
    public Date getEndDate();
}

但不幸的是,这不是它的工作原理;当我在具体类中实现此接口时; TimeRangeBuilder的实现是完全可选的。

为了让您了解我的目标,这是我的实施课程

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

import ru.crystals.videoutil.utils.TimeRange;

public class VidArchive implements TimeRange<VidArchive> {
    /** date format used to convert Date objects to human-readable form for the toString() function */
    private static final DateFormat DATE_FORMAT = new SimpleDateFormat("HH:mm:ss");

    private final byte[] bytes;
    private final String cam;
    private final Date startDate;
    private final Date endDate;
    private final String fileName;
    private final String directory;

    public static class Builder implements TimeRangeBuilder<VidArchive> {
        private byte[] bytes;
        private String cam;
        private Date startDate;
        private Date endDate;
        private String fileName;
        private String directory;

        public Builder() {}
        public Builder bytes(byte[] bytes)          { this.bytes = bytes;           return this;    }
        public Builder cam(String cam)              { this.cam = cam;               return this;    }
        @Override
        public Builder startDate(Date startDate)    { this.startDate = startDate;   return this;    }
        @Override
        public Builder endDate(Date endDate)        { this.endDate = endDate;       return this;    }
        public Builder fileName(String fileName)    { this.fileName = fileName;     return this;    }
        public Builder directory(String directory)  { this.directory = directory;   return this;    }
        @Override
        public VidArchive build()                   { return new VidArchive(this);                  }
    }

    private VidArchive(Builder builder) {
        bytes = builder.bytes;
        cam = builder.cam;
        startDate = builder.startDate;
        endDate = builder.endDate;
        fileName = builder.fileName;
        directory = builder.directory;
    }   

    public byte[] getBytes()        {   return bytes;       }
    public String getCam()          {   return cam;         }
    @Override
    public Date getStartDate()      {   return startDate;   }
    @Override
    public Date getEndDate()        {   return endDate;     }
    public String getFileName()     {   return fileName;    }
    public String getDirectory()    {   return directory;   }

    @Override
    public int compareTo(VidArchive vidArchive) {
        return startDate.compareTo(vidArchive.getStartDate());
    }

    @Override
    public String toString() {
        return DATE_FORMAT.format(startDate) + " - " + DATE_FORMAT.format(endDate);
    }
}

这一切都归结于此;我有另一个类不仅应该与VidArchive类兼容,还应该与TimeRange接口的所有实现兼容。这是我想要工作的代码

public class TimeBar<E extends TimeRange<E>> extends JProgressBar {
    private TreeSet<E> timeRanges;
    ...

    ...
    public void seekToTime() {
        /** create a dummy object (an implementation of the TimeRange interface) with the most recent date set in TimeBarUI, so that it can be compared
         *  to all the other objects in the set in order to find the closest one by time*/
        E archive = new E.Builder().
                        startDate(((TimeBarUI)ui).getMostRecentDate()).
                        endDate(((TimeBarUI)ui).getMostRecentDate()).
                        build();
        TimeRange<E> closest = timeRanges.headSet(archive, true).last();
        ...
    }
}

正如先生们可以想象的那样;整个E.Builder()的东西..是的,它不起作用。 帮助我实现它,或找到我的难题的替代解决方案(我会接受另一种Builder实现,但我非常希望保留我的Builder。

P.S。关于我的代码的任何其他建议也会受到欢迎。我总是渴望改进。

1 个答案:

答案 0 :(得分:1)

我不确定理解,但这是你想要实现的目标吗?

import java.util.Date;

public interface TimeRange<T,K> extends Comparable<T> {

  public K Builder();

  public static interface TimeRangeBuilder<T> {
    public TimeRangeBuilder<T> startDate(Date startDate);
    public TimeRangeBuilder<T> endDate(Date endDate);
    public T build();
  }

  public Date getStartDate();
  public Date getEndDate();
}

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

public class VidArchive implements TimeRange<VidArchive, VidArchive.Builder> {
  /** date format used to convert Date objects to human-readable form for the toString() function */
  private static final DateFormat DATE_FORMAT = new SimpleDateFormat("HH:mm:ss");

  private final byte[] bytes;
  private final String cam;
  private final Date startDate;
  private final Date endDate;
  private final String fileName;
  private final String directory;
  private Builder builder;

  @Override
  public Builder Builder() {
    return builder;
  }

  public static class Builder implements TimeRangeBuilder<VidArchive> {
    private byte[] bytes;
    private String cam;
    private Date startDate;
    private Date endDate;
    private String fileName;
    private String directory;
    public Builder() {}
    public Builder bytes(byte[] bytes)          { this.bytes = bytes;           return this;    }
    public Builder cam(String cam)              { this.cam = cam;               return this;    }
    @Override
    public Builder startDate(Date startDate)    { this.startDate = startDate;   return this;    }
    @Override
    public Builder endDate(Date endDate)        { this.endDate = endDate;       return this;    }
    public Builder fileName(String fileName)    { this.fileName = fileName;     return this;    }
    public Builder directory(String directory)  { this.directory = directory;   return this;    }
    @Override
    public VidArchive build()                   { return new VidArchive(this);                  }
  }



  private VidArchive(Builder builder) {
    this.builder = builder;
    bytes = builder.bytes;
    cam = builder.cam;
    startDate = builder.startDate;
    endDate = builder.endDate;
    fileName = builder.fileName;
    directory = builder.directory;
  }

  public byte[] getBytes()        {   return bytes;       }
  public String getCam()          {   return cam;         }
  @Override
  public Date getStartDate()      {   return startDate;   }
  @Override
  public Date getEndDate()        {   return endDate;     }
  public String getFileName()     {   return fileName;    }
  public String getDirectory()    {   return directory;   }

  @Override
  public int compareTo(VidArchive vidArchive) {
    return startDate.compareTo(vidArchive.getStartDate());
  }

  @Override
  public String toString() {
    return DATE_FORMAT.format(startDate) + " - " + DATE_FORMAT.format(endDate);
  }

}