Interface as functions in Kotlin












11















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
    13 hours ago
















11















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
    13 hours ago














11












11








11








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 14 hours ago









Dor MesicaDor Mesica

311316




311316













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

    – Jeel Vankhede
    13 hours ago



















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

    – Jeel Vankhede
    13 hours ago

















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

– Jeel Vankhede
13 hours ago





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

– Jeel Vankhede
13 hours ago












2 Answers
2






active

oldest

votes


















5














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































    4














    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









      5














      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




























        5














        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


























          5












          5








          5







          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 13 hours ago









          s1m0nw1s1m0nw1

          28.7k652110




          28.7k652110

























              4














              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






























                4














                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




























                  4












                  4








                  4







                  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 13 hours ago

























                  answered 13 hours ago









                  Geno ChenGeno Chen

                  2,6506925




                  2,6506925






























                      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

                      How to label and detect the document text images

                      Vallis Paradisi

                      Tabula Rosettana