Translation Instructions:

Should I define Function or Property?

Original address:Blog.kotlin-academy.com/kotlin-shou…

Original author:Igor Wojda

Lately, I’ve been confused about attributes and function usage. This is a good opportunity to introduce the concept of Kotlin attributes. So the question is, when do you use functions or when do you use properties? I suggest you follow these simple rules:

  • Properties describe state
  • Functions describe behavior

Let’s explore them further. An attribute represents a data structure that describes the state of an object. For example, a Person object can have name, lastName, and weight attributes.

class Person (var name:String, var lastName:String, var weight:Double)
Copy the code

We can also create a derived attribute that returns fullName, which is a combination of the name and lastName attributes.

class Person (var name:String, var lastName:String, var weight:Double) {
    val fullName = "$name $lastName"
}
Copy the code

In the example above, the attribute value fullName is assigned only once during the creation of the Person object. Sometimes this is an ideal behavior, but in this case, when we change the value of the name or lastName attribute, the value stored in fullName will not be updated. Fortunately, Kotlin also provides the ability to customize property accessors using getters or setters. In the following example, the value of the fullName attribute is assigned each time it is accessed.

class Person (var name:String, var lastName:String, var weight:Double) {
    val fullName
        get() = "$name $lastName"
}
Copy the code

Functions, on the other hand, contain all the behavior or actions of an object that can be performed. Our Person class can have run(),walk(), and jump() methods.

class Person () {
    fun run(a) { /*doSth*/ }

    fun walk(a) { /*doSth*/ }

    fun jump(a) { /*doSth*/}}Copy the code

It is important to note that this method may have the side effect of indirectly changing the state of the object, such as decreasing the value of the weight property in the Person object by 0.1 each time we call the jump() method

class Person (var name:String, var lastName:String, var weight:Double) {
    / /..

    fun jump(a) { 
        weight -= 0.1   
        /*doSth*/}}Copy the code

If you are still confused about when to use properties or functions, the next step is to answer the question from the external caller’s point of view. We leave the internal implementation behind (where a property is stored or how the behavior is implemented) and need to look more simply at the external API(similar to adding a third party library to a project, we just focus on the library providing the API).

person.name = "Igor"
person.weight = 79
person.jump()
person.jump()
person.jump()
Copy the code

One of the benefits of using the Kotlin property is the cleaner syntax of the property accessor (we can use height instead of the getHeight()/setHeight() methods), and the fact that getters and setters are closer to property declarations, unlike Java, We typically define member attributes at the top of a class and getter and setter methods below them. I like the attribute delegate feature, which improves the ability to reuse code. We can initialize a variable only when it’s needed (lazy delegate), and whenever the value of the property changes, You can perform actions (Observable Delegate) or implement custom delegates in another object (Android Shared Preferences, Map, Browser Session, Database…). ) to simply store our attributes.

The nice thing is that Kotlin allows us to use both functions and attributes in our interfaces

//BAD
class Person () {
    private var weight:Double = 0

    fun setWeight(weight:Double) {
        this.weight = weight
    }

    fun getWeight(a): Double {
        return weight
    }
}

//GOOD
class Person (var weight:Double)
Copy the code

When we see a method prefixed with set (e.g. SetHeight ()), a variable that takes only one argument and is specified as private, or a method prefixed with get (e.g. When a method starting with getHeight() returns a variable that is designated private, we should define a property to replace it.

Guideline: How to make this decision?

Every time you want to declare a new function, you need to ask yourself two questions:

  • “Does it describe an action?” — Use functions that describe behavior as candidates, such as run(),walk(), and jump()
  • “Does it describe a state?” — Use functions that describe state as candidates, such as name,lastName, and weight

Here is an additional set of help guides from Effective Java(if memory serves) to understand defining properties over functions.

  • No exception thrown
  • Easily and cheaply computed (or cached on the first run)
  • Returns the same result in multiple calls

The above guidelines should give you a good idea of when to use functions or attributes. Defining attributes may be a little uncomfortable at first (especially for Java developers), but trust me — after a while, it’s a wise decision.

Translator:

  • 1. Why should I translate Kotlin’s blog series?

As we all know, Kotlin is a language that has not been widely used in practical projects in China, but it is very popular in foreign countries, and many companies are also using it extensively. In this year’s Google IO, Google officials say that 35% of their engineers like to use Kotlin, so some of the kotlin-related blogs abroad are of good quality. It also includes their experience with Kotlin in some real-world projects. A language must show its value in practical application, so it is necessary to learn it. Since all foreign blogs are in English, I did some translation work and extracted some important points from my feelings on this blog. Welcome to stay tuned

  • 2. Why should I translate this blog?

We know that there is a gap between learning Kotlin’s syntax and applying it to development, and there are various choices in using it. For example, this blog is about when to define a property and when to define a function in Kotlin. This problem is not from the basic grammar learning, from the actual needs and experience to experience, for Java to Kotlin beginners, it is easy to be Java language ideas to arbitrary definition of functions. Since there are no custom accessors for properties in Java, the only way to change state is through functions. Kotlin provides an easier way to change the state of a property. So while you’re still using Kotlin in Java, really think about the advantages of writing in Kotlin.

  • 3. What is the core of this blog?

On when to use functions and when to use properties: When describing states, use properties; When describing behavior, use functions.

Here’s an example to get a feel for it again (see my previous introduction to variables and Constants for more information on custom property accessors):

Java part code example implementation

// There is no such thing as a property accessor in Kotlin for Java
// The only good way to do this in Java is to define functions, such as isIdling(), isEnded(), when you must ensure that you have the latest state
class VideoPlayer{
    public boolean isIdling(a) {// Describe the state
        return this.mPlayer ! =null && this.mPlayer.getPlaybackState() == 1;
    }

    public boolean isEnded(a) {// Describe the state
        return this.mPlayer ! =null && this.mPlayer.getPlaybackState() == 4;
    }
    
    public void play(a){// Describe the action
        //do sth    
    }
    
    public void resume(a){// Describe the action
        //do sth}}/ / call
if (mVideoPlayer.isEnded() || mVideoPlayer.isIdling()) {
    mVideoPlayer.play();         
}else{
    mVideoPlayer.resume();
}
Copy the code

Kotlin code example implementation

class VideoPlayer{
   var mIsIdling = false// Describe the state
       get() = this.mPlayer ! =null && this.mPlayer.getPlaybackState() == 1
   var mIsEnded = false// Describe the state
       get() = this.mPlayer ! =null && this.mPlayer.getPlaybackState() == 4
    
    fun play(a){// Describe the action
        //do sth    
    }
    
    fun resume(a){// Describe the action
        //do sth}}/ / call
if (mVideoPlayer.mIsEnded || mVideoPlayer.mIsIdling) {
    mVideoPlayer.play()         
}else{
    mVideoPlayer.resume()
}
Copy the code

Welcome to the Kotlin Developer Association, where the latest Kotlin technical articles are published, and a weekly Kotlin foreign technical article is translated from time to time. If you like Kotlin, welcome to join us ~~~