Hi Sergey,

This is an example of what I'm trying to do with interfaces.
Unfortunately I can't give you an example that will definitely not work because it depends on the ordering of methods by reflection.

interface Job {
    List<? extends Task> getTasks();
    // I won't bother detailing these any further, the point is that
    // the interface doesn't want a setTasks(List) method
    void addTask(Task task);
    void removeTask(Task task);
    Task findTask(String name);
    Task createTask(String name);
}
interface Task {
    List<? extends Item> getItems();
    //  As with Job, there is no Task.setItems(List) method
    void addItem(Item item);
    void removeItem(Item item);
    Task findItem(String name);
    Task createItem(String name);

    String getTaskName();
    void setTaskName(String taskName);
}
interface Item {
     String getItemName();
     void setItemName(String itemName);
}


Implementations:
class Job_Impl implements Job, Serializable {
    public List<Task_Impl> getTasks(){}
    // setTasks is ONLY used by the FIQL processing
    public void setTasks(List<Task_Impl> tasks){}
    public void addTask(Task task){}
    public void removeTask(Task task){}
    public Task findTask(String name){}
    public Task createTask(String name){}
}
class Task_Impl implements Task, Serializable {
    public List<Item_Impl> getItems();
    // setItems is ONLY used by the FIQL processing
    public void setItems(List<Item_Impl> tasks){}
    public void addItem(Item item){}
    public void removeItem(Item item){}
    public Task findItem(String name){}
    public Task createItem(String name){}

    public String getTaskName(){}
    public void setTaskName(String taskName){}
}
class Item_Impl implements Item, Serializable {
     public String getItemName(){}
     public void setItemName(String itemName){}
}


Note that I'd be perfectly happy with the Impl methods were based on interfaces:
    public List<? extends Task> getTasks(){}
    public void setTasks(List<? extends Task> tasks){}

So the problems (in no particular order):
* FIQL decides the type based on the return value of the getter, which means it needs to find a getter that returns a concrete type (because it's going to try to construct it). * Something (not sure what) requires the getter & setter to use the same types, throwing an exception if they are different (even if they are compatible). * Reflection (the JVM, I believe) considers a method with a different return type to be a different method even though there is no way to distinguish between them in Java. * Methods are returned from reflection in an unpredictable order, which means that some classes might find the getter with the implementation class return type whilst others find the getter with the interface return type.

The best I can come up with for a solution is:
1. Decide the type based on the setter.
2. Permit setters and getters to return different types as long as the setter argument type extends the getter return type. 3. Make method selection much more complicated by looking for the best getter to match the setter.

Jim

Reply via email to