tags:

views:

607

answers:

3

Can I collapse those two "getFields" methods into one using generics (the second method is intended to package private access) or should I rename the second one into something ugly like "getFieldPackagePrivate"?

public interface IField {

}


class Field implements IField { // package private class

}


  public class IForm {


     public List<IField> getFields();

  }



public class Form {
  private List<Field> fields;


  public List<IField> getFields() {
    return this.fields;

  }

  List<Field> getFields() { // package visible
    return this.fields;

  }

}

the basic usage would be like this

// by interfece - from client code

  IForm form;
  List<IField> list = form.getFields();

// by class - from other classes in the same package
  Form form2;
  List<Field> list2 = forms2.getFields();

The idea is to have a clean, save interface for an outside world and a convenient access (without downcasts) from package visible implementation clacces. My Field Class has a few methods that I don't want do be seen by a client but need to invoke from other classes in the same packege (like for example setLabel etc.)

+2  A: 

You can write (as per my answer to your previous question):

public List<? extends IField> getFields()

but you can't overload by return type, and you can't expose a package-private type in a public method.

EDIT: With the change of the question, the answer is a simple "no". You'll have to rename your other method.

Jon Skeet
I reedited it a little to make my intenntion clearer - please look agani. Thank you.
lbownik
+3  A: 

No. You can't have polymorphism based on return type in Java.

Dev er dev
A: 

After I experimented a little I found a solution based on Jon Skeet's answer

The code looks like this.

public interface IField {

}


class Field implements IField { // package private class

}


  public class IForm {


     public List<? extends IField> getFields();

  }



public class Form {
  private List<Field> fields;


  List<? extends Field> getFields() { // package visible - please note "extends Field" not "extends IField"
    return this.fields;

  }

}

now the dote below works

  IForm form;
  List<IField> list = form.getFields();

// by class - from other classes in the same package
  Form form2;
  List<Field> list2 = forms2.getFields();
lbownik
yes this is essentially covariance i guess :) anyway, doesn't this violate substitution principle? the getFields method in Form would still have to be public.
Johannes Schaub - litb
Yes, but if I make the Form class package private and use a factory class with a method that returns IFrom (I actually use it ) then everything should be ok. :]
lbownik