Kotlin interface implementation behaviour when consuming Java interface

Related searches

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?

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.

Interfaces, Interfaces in Kotlin can contain declarations of abstract methods, as well as method implementations. What makes them different from abstract classes is that � The implementer of the interface has to attach to the interface, the contract, and implement the required methods. Just like Java 8, an interface in kotlin contains the declarations of abstract methods as well as method implementations. Unlike abstract classes, an interface cannot contain state.

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);
}

Calling Kotlin from Java, For example, var firstName: String gets compiled to the following Java declarations: private String Here is an example of a Kotlin interface with a default method: // compile with However, there are cases when their behavior differs. Detailed� In Kotlin, the interface works exactly similar to Java 8, which means they can contain method implementation as well as abstract methods declaration. An interface can be implemented by a class in order to use its defined functionality. We have already introduced an example with an interface in Chapter 6 - section “anonymous inner class”.

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

Kotlin-Java interop guide, Java (for Kotlin consumption) Defining a named, single-abstract method (SAM) interface in Kotlin for the lambda type corrects the problem for Java, but� Instead of creating a class that implements a functional interface manually, you can use a lambda expression. With a SAM conversion, Kotlin can convert any lambda expression whose signature matches the signature of the interface's single method into an instance of a class that implements the interface.

Interfaces in Kotlin. Who said interfaces can't have code?, Interfaces in Java 6. The problem with Java interfaces is that we can only describe behavior, but not implement it. This is enough in many cases. But there are� With no access to the Java code, it seems to be possible only with an intermediate Java interface, see the other answer. – hotkey May 23 '17 at 11:59 1 Actually, a Kotlin intermediate interface is enough (overriding only one function with Int? paramater type). – hotkey May 23 '17 at 12:13

@JvmDefault: More Useful Than You Think, You can't manually name a nested type in a Kotlin interface Java public final class TacoImpl implements Taco { public void load() { Taco. It also exhibits the same behavior in extending interfaces as far as being duplicated in each type. Of course the library consumer will have source/target to Java 8. Become a writer on the site, in the Java, Computer Science, Scala, Linux, and Kotlin areas. Right now, we’re not hiring new authors in the Java area – only Linux, Scala, Kotlin, and Computer Science.

Use an interface if you want to define a contract.I.e. X must take Y and return Z. It doesn't care how the code is doing that. A class can implement multiple interfaces.. Use an abstract class if you want to define default behaviour in non-abstract methods so that the endusers can reuse it without rewriting it again and again.

Comments
  • Could you elaborate on that last part about referring to the implemented parent interface's initialised variables from within the child class being a "misfeature"? It seems to make sense.
  • See e.g. softwareengineering.stackexchange.com/questions/49572/… and docs.oracle.com/javase/1.5.0/docs/guide/language/….
  • Thank you, I found the second link particularly helpful. A part of the quote in the first link states, "It is of no consequence to the users of a class that the class implements a constant interface." Yet, wouldn't users of MyClass have access to MyClass().id if it implements JavaInterface?
  • Also, my question arose from the existence of this interface: developer.android.com/reference/android/provider/…. Is it good practice to use it not by "Constant Interface Antipattern" & abusing inheritance, but rather, to simply write something similar to val id: String = JavaInterface.id?
  • Regarding the second part of your main answer, I've just realised that I forgot to implement JavaInterface as part of my 5th code snippet. I've edited it; the original edit was made on mobile and the mistake wasn't apparent at the time. It is as you said, though. It seems I'm unable to access id from within MyClass, such as in arrayOf(id), in Kotlin.
  • Thanks for the response. I’ve edited my question just as two answers rolled in. If my understanding is correct, Kotlin doesn’t allow interface properties to be initialised with a value at all, while this is possible in Java. However, if I don’t "shadow" or "replace" that final Java property in my Kotlin implementation, I cannot access the property (which already has a value in Java) by name from within the implementation.
  • Yes when you declare a variable without initializing it, its marked as an abstract variable. and in byte code, kotlin creates getter and setter methods for that variable internally so you can override that variable.
  • to see how it does just declare the interface with one abstract variable and see its decompiled byte code.