#java #android #kotlin #generics #overriding
#java #Android #kotlin #общие #переопределение
Вопрос:
В Kotlin я не могу понять, можем ли мы добавить?при переопределении класса или метода. Например, следующий код:
class BaseAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>()
{
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
TODO("Not yet implemented")
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
TODO("Not yet implemented")
}
override fun getItemCount(): Int {
TODO("Not yet implemented")
}
}
Если я добавлю?внутри <>, после RecyclerView.ViewHolder , код будет скомпилирован.
Но, если я добавлю??после RecyclerView.ViewHolder в функции onBindViewHolder говорится, что:
Метод ничего не переопределяет
и код не компилируется.
Я не могу понять, почему при добавлении его внутри <> все в порядке?
Ответ №1:
Это связано с тем, что тип holder
параметра для onBindViewHolder
определяется как ненулевой в классе, который вы расширяете. Он определен в Java, поэтому он использует аннотацию для определения возможности обнуления:
public abstract void onBindViewHolder(@NonNull VH holder, int position);
Поэтому не имеет значения, является ли тип класса ненулевым или обнуляемым типом. Параметр метода определяется как ненулевая версия любого типа класса.
Не имеет значения, определяете ли вы тип как обнуляемый или нет для Adapter
класса.
Если RecyclerView.Adapter
бы они были определены в Kotlin, они, вероятно, пометили бы тип класса как ненулевой, но это невозможно сделать с помощью аннотаций Java. Я думаю, что это был бы единственный способ создать такое же ограничение на обнуляемость параметра метода в Kotlin.
Комментарии:
1. не могли бы вы объяснить, что вы имели в виду в последнем абзаце, который начинается со слова «if» и заканчивается работой «Kotlin»? особенно последнее предложение: * Я думаю, что это был бы единственный способ создать такое же ограничение на обнуляемость параметра метода в Kotlin *. Я вообще этого не понимал
2. Если вы создаете класс в Kotlin, для которого требуется, чтобы какой-либо параметр универсального типа был ненулевым, вам нужно будет пометить его как ненулевой на сайте объявления. Например, в этом случае вы бы
class Adapter<VH: ViewHolder>
вместоclass Adapter<VH: ViewHolder?>
. Если бы вы объявили его вторым способом, у вас не было бы четкого способа пометить параметр функции как ненулевую версиюVH
. (За исключением того,@NonNull
что параметр, вероятно, будет работать на самом деле. Хотя это было бы просто странно использовать в Kotlin.)3. В Java вы можете сделать это только вторым способом. Вы можете думать о родовых типах Java как всегда имеющих неявное
?
значение, потому что они всегда обнуляются на уровне класса.4. в Kotlin разве это не должно быть: class Adapter<VH: ViewHolder?> и метод: onBindViewHolder(держатель: RecyclerView.ViewHolder?) ?
5. Только если вы разрабатывали класс так, чтобы он мог обрабатывать нулевой параметр. Но это не то, как должен работать адаптер. Это гарантирует подклассам, которые
null
никогда не будут переданы этому методу, поэтому, когда вы его подклассируете, вам не нужно беспокоиться о проверке, является ли держатель null .