Interface as functions in Kotlin





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}







13















I am working on an android library that contains some views. Naturally these views can emit events.



I have an interface called (just for the purpose of this question) Listener. If I wrote the library in Java things would look like this:



public interface Listener {
void onEvent();
}


public class SomeView extends FrameLayout {
// Some more functions and implementation details

public void setListener(Listener l) { ... }
}


When using this view in a Kotlin activity I can use the setListener like this:



someViewInstance.setListener {
// implementation
}


I want to write my library in Kotlin, but it might be used in Java code as well, so I want to provide and interface for the listener just like a regular view (like above) but have the option for Kotlin code to use the function implementation:



interface Listener {
fun onEvent()
}


when I try to use setListener like above in my Kotlin test activity I get a compilation error saying that the function expects type Listener but got () -> Unit.



Is there a way to enable this kind of implementation in Kotlin without having to create a new function for this?



I thought about having just one function that receives () -> Unit but then it look weird in the Java code (Function1 etc.).



Thanks!










share|improve this question























  • You might wanna check this link : kotlinlang.org/docs/reference/lambdas.html

    – Jeel Vankhede
    Mar 12 at 8:27


















13















I am working on an android library that contains some views. Naturally these views can emit events.



I have an interface called (just for the purpose of this question) Listener. If I wrote the library in Java things would look like this:



public interface Listener {
void onEvent();
}


public class SomeView extends FrameLayout {
// Some more functions and implementation details

public void setListener(Listener l) { ... }
}


When using this view in a Kotlin activity I can use the setListener like this:



someViewInstance.setListener {
// implementation
}


I want to write my library in Kotlin, but it might be used in Java code as well, so I want to provide and interface for the listener just like a regular view (like above) but have the option for Kotlin code to use the function implementation:



interface Listener {
fun onEvent()
}


when I try to use setListener like above in my Kotlin test activity I get a compilation error saying that the function expects type Listener but got () -> Unit.



Is there a way to enable this kind of implementation in Kotlin without having to create a new function for this?



I thought about having just one function that receives () -> Unit but then it look weird in the Java code (Function1 etc.).



Thanks!










share|improve this question























  • You might wanna check this link : kotlinlang.org/docs/reference/lambdas.html

    – Jeel Vankhede
    Mar 12 at 8:27














13












13








13








I am working on an android library that contains some views. Naturally these views can emit events.



I have an interface called (just for the purpose of this question) Listener. If I wrote the library in Java things would look like this:



public interface Listener {
void onEvent();
}


public class SomeView extends FrameLayout {
// Some more functions and implementation details

public void setListener(Listener l) { ... }
}


When using this view in a Kotlin activity I can use the setListener like this:



someViewInstance.setListener {
// implementation
}


I want to write my library in Kotlin, but it might be used in Java code as well, so I want to provide and interface for the listener just like a regular view (like above) but have the option for Kotlin code to use the function implementation:



interface Listener {
fun onEvent()
}


when I try to use setListener like above in my Kotlin test activity I get a compilation error saying that the function expects type Listener but got () -> Unit.



Is there a way to enable this kind of implementation in Kotlin without having to create a new function for this?



I thought about having just one function that receives () -> Unit but then it look weird in the Java code (Function1 etc.).



Thanks!










share|improve this question














I am working on an android library that contains some views. Naturally these views can emit events.



I have an interface called (just for the purpose of this question) Listener. If I wrote the library in Java things would look like this:



public interface Listener {
void onEvent();
}


public class SomeView extends FrameLayout {
// Some more functions and implementation details

public void setListener(Listener l) { ... }
}


When using this view in a Kotlin activity I can use the setListener like this:



someViewInstance.setListener {
// implementation
}


I want to write my library in Kotlin, but it might be used in Java code as well, so I want to provide and interface for the listener just like a regular view (like above) but have the option for Kotlin code to use the function implementation:



interface Listener {
fun onEvent()
}


when I try to use setListener like above in my Kotlin test activity I get a compilation error saying that the function expects type Listener but got () -> Unit.



Is there a way to enable this kind of implementation in Kotlin without having to create a new function for this?



I thought about having just one function that receives () -> Unit but then it look weird in the Java code (Function1 etc.).



Thanks!







android kotlin






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Mar 12 at 8:10









Dor MesicaDor Mesica

321316




321316













  • You might wanna check this link : kotlinlang.org/docs/reference/lambdas.html

    – Jeel Vankhede
    Mar 12 at 8:27



















  • You might wanna check this link : kotlinlang.org/docs/reference/lambdas.html

    – Jeel Vankhede
    Mar 12 at 8:27

















You might wanna check this link : kotlinlang.org/docs/reference/lambdas.html

– Jeel Vankhede
Mar 12 at 8:27





You might wanna check this link : kotlinlang.org/docs/reference/lambdas.html

– Jeel Vankhede
Mar 12 at 8:27












2 Answers
2






active

oldest

votes


















6














You can define your interface as suggested and also add an extension that allows the usage of a lambda which is more idimatic for Kotlin code.



class SomeView {
fun setListener(l: Listener) {}
}

fun SomeView.setListener(l: () -> Unit) = setListener(object : Listener {
override fun onEvent() = l()
})


In Java, you would still be able to pass the Listener implementation.






share|improve this answer
























  • I tried to define the extension function in the same file as the class itself and then use it in the activity, but it didn't work. Only when I defined the extension in the activity did it work. I am working on a library so it is not an option to define the extension with the activity. Have I missed something?

    – Dor Mesica
    Mar 13 at 10:01













  • it's important that you don't define the extension inside a class body but on top-level

    – s1m0nw1
    Mar 13 at 10:08











  • It's not in the type body. I defined it right after the class definition. After the last } of the class

    – Dor Mesica
    Mar 13 at 10:10













  • what happens if you import it in your activity? try import packagename.extensionName with your extension named extensionName and defined in package packagename

    – s1m0nw1
    Mar 13 at 10:11











  • I works.. I forgot to import it. Thanks!

    – Dor Mesica
    Mar 13 at 10:12



















5














This is called SAM-conversions,




Just like Java 8, Kotlin supports SAM conversions. This means that Kotlin function literals can be automatically converted into implementations of Java interfaces with a single non-default method, as long as the parameter types of the interface method match the parameter types of the Kotlin function.




But




Note that SAM conversions only work for interfaces, not for abstract classes, even if those also have just a single abstract method.

Also note that this feature works only for Java interop; since Kotlin has proper function types, automatic conversion of functions into implementations of Kotlin interfaces is unnecessary and therefore unsupported.




So, you can't write a simple Kotlin code to simulate this call.





In Java, if you write a



public interface Listener {
void onEvent(); // SAM: Single Abstract Method. Only 1 is allowed
}


And you have a



public class SomeView extends FrameLayout {
// skip the constructors

public void setListener(Listener listener) {
// do something
}
}


Then you can do such a fancy call in Kotlin, thanks to SAM-conversion:



SomeView(this).setListener {} // asking a parameter with type () -> Unit for setListener
// Then parenthesis of function call can be omitted
// setListener function can also accept a parameter with type Listener
// by object : Listener {}


But if you convert that Java file into Kotlin, the code will report an error, due to the reason mentioned above. You have to implement a SomeView.setListener(() -> Unit) function by yourself, for example



fun SomeView.setListener(l: () -> Unit) {
listener = object : Listener{
override fun onEvent() {
l()
}
}
}





share|improve this answer


























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55116769%2finterface-as-functions-in-kotlin%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    6














    You can define your interface as suggested and also add an extension that allows the usage of a lambda which is more idimatic for Kotlin code.



    class SomeView {
    fun setListener(l: Listener) {}
    }

    fun SomeView.setListener(l: () -> Unit) = setListener(object : Listener {
    override fun onEvent() = l()
    })


    In Java, you would still be able to pass the Listener implementation.






    share|improve this answer
























    • I tried to define the extension function in the same file as the class itself and then use it in the activity, but it didn't work. Only when I defined the extension in the activity did it work. I am working on a library so it is not an option to define the extension with the activity. Have I missed something?

      – Dor Mesica
      Mar 13 at 10:01













    • it's important that you don't define the extension inside a class body but on top-level

      – s1m0nw1
      Mar 13 at 10:08











    • It's not in the type body. I defined it right after the class definition. After the last } of the class

      – Dor Mesica
      Mar 13 at 10:10













    • what happens if you import it in your activity? try import packagename.extensionName with your extension named extensionName and defined in package packagename

      – s1m0nw1
      Mar 13 at 10:11











    • I works.. I forgot to import it. Thanks!

      – Dor Mesica
      Mar 13 at 10:12
















    6














    You can define your interface as suggested and also add an extension that allows the usage of a lambda which is more idimatic for Kotlin code.



    class SomeView {
    fun setListener(l: Listener) {}
    }

    fun SomeView.setListener(l: () -> Unit) = setListener(object : Listener {
    override fun onEvent() = l()
    })


    In Java, you would still be able to pass the Listener implementation.






    share|improve this answer
























    • I tried to define the extension function in the same file as the class itself and then use it in the activity, but it didn't work. Only when I defined the extension in the activity did it work. I am working on a library so it is not an option to define the extension with the activity. Have I missed something?

      – Dor Mesica
      Mar 13 at 10:01













    • it's important that you don't define the extension inside a class body but on top-level

      – s1m0nw1
      Mar 13 at 10:08











    • It's not in the type body. I defined it right after the class definition. After the last } of the class

      – Dor Mesica
      Mar 13 at 10:10













    • what happens if you import it in your activity? try import packagename.extensionName with your extension named extensionName and defined in package packagename

      – s1m0nw1
      Mar 13 at 10:11











    • I works.. I forgot to import it. Thanks!

      – Dor Mesica
      Mar 13 at 10:12














    6












    6








    6







    You can define your interface as suggested and also add an extension that allows the usage of a lambda which is more idimatic for Kotlin code.



    class SomeView {
    fun setListener(l: Listener) {}
    }

    fun SomeView.setListener(l: () -> Unit) = setListener(object : Listener {
    override fun onEvent() = l()
    })


    In Java, you would still be able to pass the Listener implementation.






    share|improve this answer













    You can define your interface as suggested and also add an extension that allows the usage of a lambda which is more idimatic for Kotlin code.



    class SomeView {
    fun setListener(l: Listener) {}
    }

    fun SomeView.setListener(l: () -> Unit) = setListener(object : Listener {
    override fun onEvent() = l()
    })


    In Java, you would still be able to pass the Listener implementation.







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Mar 12 at 8:29









    s1m0nw1s1m0nw1

    30.3k656111




    30.3k656111













    • I tried to define the extension function in the same file as the class itself and then use it in the activity, but it didn't work. Only when I defined the extension in the activity did it work. I am working on a library so it is not an option to define the extension with the activity. Have I missed something?

      – Dor Mesica
      Mar 13 at 10:01













    • it's important that you don't define the extension inside a class body but on top-level

      – s1m0nw1
      Mar 13 at 10:08











    • It's not in the type body. I defined it right after the class definition. After the last } of the class

      – Dor Mesica
      Mar 13 at 10:10













    • what happens if you import it in your activity? try import packagename.extensionName with your extension named extensionName and defined in package packagename

      – s1m0nw1
      Mar 13 at 10:11











    • I works.. I forgot to import it. Thanks!

      – Dor Mesica
      Mar 13 at 10:12



















    • I tried to define the extension function in the same file as the class itself and then use it in the activity, but it didn't work. Only when I defined the extension in the activity did it work. I am working on a library so it is not an option to define the extension with the activity. Have I missed something?

      – Dor Mesica
      Mar 13 at 10:01













    • it's important that you don't define the extension inside a class body but on top-level

      – s1m0nw1
      Mar 13 at 10:08











    • It's not in the type body. I defined it right after the class definition. After the last } of the class

      – Dor Mesica
      Mar 13 at 10:10













    • what happens if you import it in your activity? try import packagename.extensionName with your extension named extensionName and defined in package packagename

      – s1m0nw1
      Mar 13 at 10:11











    • I works.. I forgot to import it. Thanks!

      – Dor Mesica
      Mar 13 at 10:12

















    I tried to define the extension function in the same file as the class itself and then use it in the activity, but it didn't work. Only when I defined the extension in the activity did it work. I am working on a library so it is not an option to define the extension with the activity. Have I missed something?

    – Dor Mesica
    Mar 13 at 10:01







    I tried to define the extension function in the same file as the class itself and then use it in the activity, but it didn't work. Only when I defined the extension in the activity did it work. I am working on a library so it is not an option to define the extension with the activity. Have I missed something?

    – Dor Mesica
    Mar 13 at 10:01















    it's important that you don't define the extension inside a class body but on top-level

    – s1m0nw1
    Mar 13 at 10:08





    it's important that you don't define the extension inside a class body but on top-level

    – s1m0nw1
    Mar 13 at 10:08













    It's not in the type body. I defined it right after the class definition. After the last } of the class

    – Dor Mesica
    Mar 13 at 10:10







    It's not in the type body. I defined it right after the class definition. After the last } of the class

    – Dor Mesica
    Mar 13 at 10:10















    what happens if you import it in your activity? try import packagename.extensionName with your extension named extensionName and defined in package packagename

    – s1m0nw1
    Mar 13 at 10:11





    what happens if you import it in your activity? try import packagename.extensionName with your extension named extensionName and defined in package packagename

    – s1m0nw1
    Mar 13 at 10:11













    I works.. I forgot to import it. Thanks!

    – Dor Mesica
    Mar 13 at 10:12





    I works.. I forgot to import it. Thanks!

    – Dor Mesica
    Mar 13 at 10:12













    5














    This is called SAM-conversions,




    Just like Java 8, Kotlin supports SAM conversions. This means that Kotlin function literals can be automatically converted into implementations of Java interfaces with a single non-default method, as long as the parameter types of the interface method match the parameter types of the Kotlin function.




    But




    Note that SAM conversions only work for interfaces, not for abstract classes, even if those also have just a single abstract method.

    Also note that this feature works only for Java interop; since Kotlin has proper function types, automatic conversion of functions into implementations of Kotlin interfaces is unnecessary and therefore unsupported.




    So, you can't write a simple Kotlin code to simulate this call.





    In Java, if you write a



    public interface Listener {
    void onEvent(); // SAM: Single Abstract Method. Only 1 is allowed
    }


    And you have a



    public class SomeView extends FrameLayout {
    // skip the constructors

    public void setListener(Listener listener) {
    // do something
    }
    }


    Then you can do such a fancy call in Kotlin, thanks to SAM-conversion:



    SomeView(this).setListener {} // asking a parameter with type () -> Unit for setListener
    // Then parenthesis of function call can be omitted
    // setListener function can also accept a parameter with type Listener
    // by object : Listener {}


    But if you convert that Java file into Kotlin, the code will report an error, due to the reason mentioned above. You have to implement a SomeView.setListener(() -> Unit) function by yourself, for example



    fun SomeView.setListener(l: () -> Unit) {
    listener = object : Listener{
    override fun onEvent() {
    l()
    }
    }
    }





    share|improve this answer






























      5














      This is called SAM-conversions,




      Just like Java 8, Kotlin supports SAM conversions. This means that Kotlin function literals can be automatically converted into implementations of Java interfaces with a single non-default method, as long as the parameter types of the interface method match the parameter types of the Kotlin function.




      But




      Note that SAM conversions only work for interfaces, not for abstract classes, even if those also have just a single abstract method.

      Also note that this feature works only for Java interop; since Kotlin has proper function types, automatic conversion of functions into implementations of Kotlin interfaces is unnecessary and therefore unsupported.




      So, you can't write a simple Kotlin code to simulate this call.





      In Java, if you write a



      public interface Listener {
      void onEvent(); // SAM: Single Abstract Method. Only 1 is allowed
      }


      And you have a



      public class SomeView extends FrameLayout {
      // skip the constructors

      public void setListener(Listener listener) {
      // do something
      }
      }


      Then you can do such a fancy call in Kotlin, thanks to SAM-conversion:



      SomeView(this).setListener {} // asking a parameter with type () -> Unit for setListener
      // Then parenthesis of function call can be omitted
      // setListener function can also accept a parameter with type Listener
      // by object : Listener {}


      But if you convert that Java file into Kotlin, the code will report an error, due to the reason mentioned above. You have to implement a SomeView.setListener(() -> Unit) function by yourself, for example



      fun SomeView.setListener(l: () -> Unit) {
      listener = object : Listener{
      override fun onEvent() {
      l()
      }
      }
      }





      share|improve this answer




























        5












        5








        5







        This is called SAM-conversions,




        Just like Java 8, Kotlin supports SAM conversions. This means that Kotlin function literals can be automatically converted into implementations of Java interfaces with a single non-default method, as long as the parameter types of the interface method match the parameter types of the Kotlin function.




        But




        Note that SAM conversions only work for interfaces, not for abstract classes, even if those also have just a single abstract method.

        Also note that this feature works only for Java interop; since Kotlin has proper function types, automatic conversion of functions into implementations of Kotlin interfaces is unnecessary and therefore unsupported.




        So, you can't write a simple Kotlin code to simulate this call.





        In Java, if you write a



        public interface Listener {
        void onEvent(); // SAM: Single Abstract Method. Only 1 is allowed
        }


        And you have a



        public class SomeView extends FrameLayout {
        // skip the constructors

        public void setListener(Listener listener) {
        // do something
        }
        }


        Then you can do such a fancy call in Kotlin, thanks to SAM-conversion:



        SomeView(this).setListener {} // asking a parameter with type () -> Unit for setListener
        // Then parenthesis of function call can be omitted
        // setListener function can also accept a parameter with type Listener
        // by object : Listener {}


        But if you convert that Java file into Kotlin, the code will report an error, due to the reason mentioned above. You have to implement a SomeView.setListener(() -> Unit) function by yourself, for example



        fun SomeView.setListener(l: () -> Unit) {
        listener = object : Listener{
        override fun onEvent() {
        l()
        }
        }
        }





        share|improve this answer















        This is called SAM-conversions,




        Just like Java 8, Kotlin supports SAM conversions. This means that Kotlin function literals can be automatically converted into implementations of Java interfaces with a single non-default method, as long as the parameter types of the interface method match the parameter types of the Kotlin function.




        But




        Note that SAM conversions only work for interfaces, not for abstract classes, even if those also have just a single abstract method.

        Also note that this feature works only for Java interop; since Kotlin has proper function types, automatic conversion of functions into implementations of Kotlin interfaces is unnecessary and therefore unsupported.




        So, you can't write a simple Kotlin code to simulate this call.





        In Java, if you write a



        public interface Listener {
        void onEvent(); // SAM: Single Abstract Method. Only 1 is allowed
        }


        And you have a



        public class SomeView extends FrameLayout {
        // skip the constructors

        public void setListener(Listener listener) {
        // do something
        }
        }


        Then you can do such a fancy call in Kotlin, thanks to SAM-conversion:



        SomeView(this).setListener {} // asking a parameter with type () -> Unit for setListener
        // Then parenthesis of function call can be omitted
        // setListener function can also accept a parameter with type Listener
        // by object : Listener {}


        But if you convert that Java file into Kotlin, the code will report an error, due to the reason mentioned above. You have to implement a SomeView.setListener(() -> Unit) function by yourself, for example



        fun SomeView.setListener(l: () -> Unit) {
        listener = object : Listener{
        override fun onEvent() {
        l()
        }
        }
        }






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Mar 12 at 8:52

























        answered Mar 12 at 8:40









        Geno ChenGeno Chen

        2,76561125




        2,76561125






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55116769%2finterface-as-functions-in-kotlin%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Index of /

            Tribalistas

            Filisteus