Абстрактный метод массива заданной длины в Java?

Я пытаюсь создать метод абстрактного массива, который указывает, что этот абстрактный объект массива может содержать только 3 элемента.

Теперь я попытался сделать что-то вроде этого public abstract BaseAdapter[3] adapters(); но он жалуется с ошибкой, что это не может быть сделано таким образом.

это их другой способ или мне нужно просто сделать public abstract BaseAdapter[] adapters();?

Это будет хорошо работать, но подкласс все еще может передавать массив размером более 3 элементов.

7 ответов

Решение

Вы можете решить это так:

  • Создайте абстрактный вспомогательный метод (который вы можете переопределить) с именем createAdapters() с типом возврата BaseAdapter[]

    protected abstract BaseAdapter[] createAdapters();
    
  • В вашем суперклассе у вас есть последний метод adapters это делает следующее:

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

Другой альтернативой может быть создание простого класса с именем BaseAdapterTriple (возможно, с более описательным именем), содержащим три BaseAdapter, и используйте их в качестве возвращаемого значения.

Насколько я знаю, нет способа наложить подобные ограничения на объекты в сигнатуре метода. Либо используйте исключения при реализации методов, либо используйте пользовательские классы.

Вы, кажется, неправильно понимаете значение abstract Модификатор в Java.

abstract применяется к классам и методам, а не к полям / переменным, поэтому то, что вы пытаетесь, не может работать.

Пожалуйста, опишите, чего вы хотите достичь, тогда мы можем помочь:-).

Смотрите, например, http://download.oracle.com/javase/tutorial/java/IandI/abstract.html для объяснения abstract,

В Java размер массива не является частью его типа. Или, другими словами, все типы массивов с заданным базовым типом одинаковы. Кроме того, вы не можете подписать метод, который накладывает ограничения на размер типизированного параметра или результата массива.

Это означает, что у вас остается кодирование метода для проверки (в вашем случае) длины массива, который он собирается вернуть. Это, вероятно, не очень вам поможет, так как я предполагаю, что вы пытаетесь использовать статическую типизацию для обеспечения "тройственности" ваших массивов. С этой точки зрения ответ @matt b на деньги, хотя вы могли бы сделать это таким образом, чтобы получить массивы (длиной 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;
    }
}

Таким образом, вы не можете применять статические ограничения размера массива в Java. Вы должны делать это динамически, но вы можете предпринять шаги, чтобы избежать ошибок во время выполнения.

Ответ aioobe - хороший подход, но я бы также предложил кое-что немного другое:

Если вам требуется, чтобы метод возвращал массив определенного размера, вы, возможно, захотите задать вопрос, почему массив является подходящим типом возврата для этого метода, в первую очередь, вместо того, чтобы использовать простой POJO, который может легко инкапсулировать идею "3 BaseAdapters", то есть:

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

Всем понятнее, если вы инкапсулируете идею "вернуть 3 адаптера" в его собственный класс, чтобы его можно было использовать в качестве возвращаемого типа (конечно, вы можете найти более подходящее имя для класса).

Нет, вы не можете сделать это ни с массивами, ни списками. Вы можете выдать исключение, если число превышает 3, и задокументировать это поведение.

Если вы хотите adapters() метод, который может вернуть только 3 BaseAdapter самое большее и имея подклассы для реализации "возврата", соблюдая при этом контракт 3max, вы должны выполнить проверку в своем adapters() метод, и вызвать abstract метод.

Например:

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

    protected abstract BaseAdapter[] internalAdapters();
}
Другие вопросы по тегам