2017-05-17 1 views
12

Je reçois cette erreur dans Kotlin dans cette partie:override accidentelle: Les déclarations suivantes ont la même signature JVM

class GitHubRepoAdapter(private val context: Context, 
    private val values: List<GithubRepo>) : ArrayAdapter<GithubRepo>(context, R.layout.list_item, 
    values) { 

contexte privé val: Contexte

dans le journal, il dit:

Error:(14, 25) Accidental override: The following declarations have the same JVM signature (getContext()Landroid/content/Context;): fun(): Context fun getContext(): Context!

Je ne suis pas en mesure de voir ce qui cause le problème.

Répondre

24

Cela se produit parce que le compilateur Kotlin tente de générer un getter pour val context déclaré dans votre classe constructeur principal, à savoir une fonction getContext(), mais la classe de base ArrayAdapter<T> already has such a function.

Vous pouvez résoudre ce en effectuant l'une des opérations suivantes:

  • Changer votre classe paramètre constructeur de ne pas être un val.

    class GitHubRepoAdapter(context: Context, ... 
    

    Dans ce cas, le getter ne sera pas généré et le conflit disparaîtra.

    Cela semble être la solution préférable dans votre cas, car, même sans redéclaration, there is already a synthetic property context inferred from the Java getter.

  • Utilisez l'annotation @JvmName, apply it to the context property getter:

    class GitHubRepoAdapter(@get:JvmName("getContext_") private val context: Context, ... 
    

    Cela rendra le compilateur générer le getter avec un autre nom JVM (celui spécifié dans l'annotation), évitant ainsi le conflit, mais en faisant accéder à partir Java moins intuitif (d'autant qu'il y aura deux fonctions similaires). Dans Kotlin, vous serez toujours en mesure d'utiliser la propriété avec son nom d'origine context.

4

En plus de la réponse déjà donnée ...

  • Ou, vous pouvez garder val (ou var), mais changer le nom du paramètre à quelque chose qui ne sont pas en collision avec le super déclaration de classe.

Dans une déclaration de classe, les paramètres dans les déclarations de constructeur sont souvent plus que de simples paramètres. En utilisant val ou var, vous déclarez réellement des membres de propriété (pas seulement des paramètres). Et avec les membres de la propriété viennent automatiques "getters" (et "setters" dans le cas de var). Le getter automatique, dans le cas de l'OP, est appelé getContext()mais la classe de base a déjà un getContext() (même signature). Le plus souvent, l'intention ici était simplement de passer le context au super, auquel cas, l'autre réponse fonctionne le mieux. Mais, dans le cas où une nouvelle propriété est souhaitée, mais le nom choisi entre en collision avec un membre du super-objet, le changement de nom est l'alternative.

En bref, en changeant le nom applique lorsque vous ne veulent une nouvelle variable membre mais une super classe expose déjà un autre membre du même nom.

+0

Je pense que cette version est en fait plus préférable à la réponse acceptée. Si ma super classe a déjà une propriété/getter/setter pour une variable, pourquoi en créer une seconde? Supprimer 'val/var' semble le moyen le plus simple d'y aller à coup sûr. – withoutclass

+0

@withoutclass - vous ne comprenez pas ma réponse, la mienne dit en fait que vous pouvez garder le val ou var et juste changer le nom de la variable, ce qui est utile lorsque la super classe utilise déjà le prénom que vous avez choisi. Dans le cas où la super classe utilise le nom d'une propriété avec un objectif entièrement différent de celui que vous aviez prévu pour votre variable, alors une nouvelle propriété est appropriée en utilisant un nom différent. Je vais mettre à jour ma réponse pour le rendre plus clair. – Les