Абстрактный метод массива заданной длины в 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();
}