Kotlin - Extension for final class

2019-08-10 20:31发布

Is it possible to create extension of final classes like String? Like in swift it is possible to add additional methods inside a extension of final class.

For an example - I would like to create a method in String extension which will tell me String have valid length for password.

 val password : String = mEdtPassword!!.getText().toString()

 // how to define haveValidLength method in extension
 val isValid : Boolean = password.haveValidLength()

Note - That example is just for a sake to understand usability of extension, not a real scenario.

3条回答
Lonely孤独者°
2楼-- · 2019-08-10 20:51

You can do that with extension functions in Kotlin. With extensions, you are able to add extra functionality to a class that you do or do not have access to; for example a legacy code base. In the example given in the Kotlin docs here, swap was added to MutableList<Int> which doesn't have swap originally. A this keyword is used that refers to the object that the swap functionality will operate on. In the example below, this refers to testList

val testList = mutableListOf(1, 2, 3)
testList.swap(0, 2)
查看更多
Deceive 欺骗
3楼-- · 2019-08-10 20:54

Trying to add more detail, this answer might be helpful for someone.

Yes we can add additional methods to final classes like String. For an example I would like to add one method in String which will tell me that my String have valid number of characters for password or not.

So what I have to do is, I have ti create a below function which can be written in same class or at different separate class file.

    fun String.hasValidPassword() : Boolean {

 // Even no need to send string from outside, use 'this' for reference of a String

     return !TextUtils.isEmpty(this) && this.length > 6
    }

And now from anywhere call

    val isValid : Boolean = password.haveValidLength()

Suggestion

If your application just has a single password validation, then there is no problem.

However, I don't suggest you write such a extension method hasValidPassword if the application has more than one validation. since the extension method is satically, you can't change your hasValidPassword in runtime. So if you want to change the validation in runtime, you should using a function instead, for example:

class PasswordRepository(private val validate:(String)->Boolean){
    fun save(value:String){
        if(validate(value)){
            //TODO persist the password
        }
    }
}

val permitAll = PasswordRepository {true}
val denyAll = PasswordRepository {false}

permitAll.save("it will be persisted")
denyAll.save("it will not be persisted")

In other words, the extension method above violates Single Responsibility Principle, it does validation & string operations.

查看更多
该账号已被封号
4楼-- · 2019-08-10 20:57

yes, you can. Kotin extension method provides the ability to extend a class with new functionality without having to inherit from the class or use any type of design pattern such as Decorator.

Below is an extension method for a String:

//  v--- the extension method receiver type
fun String.at(value: Int) = this[value]

And the extension method code generated as Java below:

public static char at(String receiver, int value){
    return receiver.charAt(value);
}

So an extension method in Kotlin is using delegation rather than inheritance.

Then you can calling an extension method like as its member function as below:

println("bar".at(1))//println 'a'

You also can write an extension method for the existing extension function, for example:

fun String.substring(value: Int): String = TODO()

//    v--- throws exception rather than return "ar"
"bar".substring(1)

But you can't write an extension method for the existing member function, for example:

operator fun String.get(value: Int): Char = TODO()

//   v--- return 'a' rather than throws an Exception
val second = "bar"[1]
查看更多
登录 后发表回答