简体   繁体   中英

Kotlin interface implementation behaviour when consuming Java interface

If I have an interface in Kotlin:

interface KotlinInterface {
    val id: String
}

I can implement it like so:

class MyClass : KotlinInterface {
    override val id: String = "id"
}

However, if I were to consume a Java interface like this:

public interface JavaInterface {
    String id = "id";
}

I cannot override the id class variable in a similar way:

class MyClass : JavaInterface {
    override val myId: String = JavaInterface.id //linter says: 'myId' overrides nothing
}

I also cannot make use of id elsewhere despite it having a predefined value:

class MyClass : JavaInterface {
    val myArray: Array<String> = arrayOf(id) // linter would say that id is not defined rather than recognising it as the string “id”
}

It appears I have to use it like so:

class MyClass {
    val id: String = JavaInterface.id
    val myArray: Array<String> = arrayOf(id)
}

Could anyone explain this difference in behaviour and point out anything I may be understanding wrongly?

In the java interface, every variable is a static final variable and static variables can't be overridden. That is why you see that lint warning.

Edit 1:

Kotlin interface

  interface Ser {
       var name: String //abstract
    }

is Equivalent to java interface

public interface Ser {
   @NotNull
   String getName();

   void setName(@NotNull String var1);
}

I cannot override the id class variable in a similar way:

You can't do it in Java either; the equivalent would be

class MyClass implements JavaInterface {
    @Override String getMyId() {
        return JavaInterface.id;
    }
}

getMyId doesn't override anything.

And if you write in Java

class MyClass implements JavaInterface {
    String id = JavaInterface.id;
}

you aren't overriding anything, because you can't override fields (in addition, MyClass.id is a non-final instance package-private field, while JavaInterface.id is implicitly a final static public field because interfaces don't allow any other kind).

I also cannot make use of id elsewhere despite it having a predefined value:

Again, same as in Java; you need JavaInterface.id in both Java and Kotlin, or import some.package.JavaInterface.id to use just id ( import static in Java).

There is a difference if MyClass implements JavaInterface , because then in Java you can refer to JavaInterface.id as MyClass.id or as someInstanceOfMyClass.id ; and inside MyClass just as id . But this is often considered a misfeature, so Kotlin's designers avoided it.

You declared constant (public static String id = "id") at Java interface.

Whereas Kotlin interface declared abstract property. See Kotlin reference: https://kotlinlang.org/docs/reference/interfaces.html

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM