views:

128

answers:

8

Hi, i am trying to create a abstract array method that specify's that this abstract object of an array can only hold 3 items.

Now i have tried doing something like this public abstract BaseAdapter[3] adapters(); but it complains with an error that it cant be done this way.

is their another way or do i need to just do public abstract BaseAdapter[] adapters();?

That will work fine but the sub class can still pass an array larger than 3 items

A: 

You can throw exception if size is greater than 3 .

org.life.java
A: 

You seem to misunderstand the meaning of the abstract modifier in Java.

abstract applies to classes and methods, not to fields / variables, so what you are trying cannot work.

Please describe what you want to accomplish, then we can help :-).

See e.g. http://download.oracle.com/javase/tutorial/java/IandI/abstract.html for an explanation of abstract.

sleske
+1  A: 

As far as I'm aware there is no way to place restrictions like that on objects in a method signature. Either use exceptions in implementing methods, or use custom classes.

Andy
A: 

No, you can't do this neither with arrays nor lists. You can throw an exception if number exceeds 3 and document this behavior.

Roman
+5  A: 

You could solve it like this:

  • Create an abstract helper method (which you can override) named createAdapters() with return type BaseAdapter[]

    protected abstract BaseAdapter[] createAdapters();
    
  • In your super-class you have a final method adapters that does the following:

    public final BaseAdapter[] adapters() {
        BaseAdapter[] adapters = createAdapters();
        if (adapters.length != 3)
            throw new Exception("Error: Please return 3 adapters.");
        return adapters;
    }
    

Another alternative would be to create a simple class called BaseAdapterTriple (perhaps with a more descriptive name) containing the three BaseAdapters, and use that as return value.

aioobe
So please declare the method as final :)
pgras
ah, thanks, fixed
aioobe
A: 

If you want an adapters() method which can only return 3 BaseAdapter at most and having subclasses to implement the "return" themselves while respecting the 3max contract, you should do the verification in your adapters() method, and invoke an abstract method.

For example :

abstract class YourAbstractClass{
    public BaseAdapter[] adapters(){
        BaseAdapter[] adapters = internalAdapters();
        if(adapters.length > 3){
            throw new IllegalStateException();
        }
        return adapters;
    }

    protected abstract BaseAdapter[] internalAdapters();
}
Colin Hebert
A: 

aioobe's answer is a good approach to take, but I'd also suggest something a little bit different:

If you are requiring a method to return an array of a certain size, you might want to question why an array is the appropriate return type for this method in the first place, rather than using a simple POJO which can easily encapsulate the idea of "3 BaseAdapters", i.e.:

public class ThreeAdapters {
    BaseAdapter getAdapter1() { ...}
    BaseAdapter getAdapter2() { ...}
    BaseAdapter getAdapter3() { ...}
}

It's a lot clearer to everyone involved if you encapsulate the idea of "return 3 adapters" into it's own class so that this can be used as the return type (of course, you may find a more appropriate name for the class).

matt b
A: 

In Java, the size of an array is not part of its type. Or to put it another way, all array types with a given base type are the same. Furthermore, you cannot a method signature that places restrictions on the size of an array typed parameter or result.

This means that you are left with the coding the method to test (in your case) the length of the array it is about to return. This is probably not going to help you much, since I assume that you are trying leverage static typing to enforce the "tripleness" of your arrays. From this perspective @matt b's answer is on the money, though you could make do it in a way that still gives you arrays (of length 3):

public class AdapterTriple {
    private Adapter[] adapters;
    /**
     * This constructor may throw an exception
     */
    public AdapterTriple(Adapter[] adapters) {
        if (adapters.length != 3) {
            throw new IllegalArgumentException("array length is wrong");
        }
        this.adapters = adapters;
    }
    /**
     * This constructor won't throw an exception (apart from Errors)
     */
    public AdapterTriple(Adapter adapter1, Adapter adapter2, Adapter adapter3) {
        this.adapters = adapters = new Adapters[] {
                adapter1, adapter2, adapter3};
    }
    /**
     * @return an array of 3 adapters.
     */
    public Adapter[] {
        return adapters;
    }
}

In summary, you cannot enforce array size constraints statically in Java. You have to do it dynamically, but you can take steps to make runtime errors unlikely.

Stephen C