Kotlin - final class 的扩展

Kotlin - Extension for final class

是否可以像字符串一样创建 final 类 的扩展?就像在 swift 中一样,可以在 final class.

extension 中添加其他方法

举个例子 - 我想在 String 扩展中创建一个方法,它会告诉我 String 有有效的密码长度。

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

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

注意 - 该示例只是为了了解 extension 的可用性,而不是真实场景。

是的,你可以。 Kotin extension method 提供了使用新功能 扩展 class 的能力,而无需继承 class 或使用任何类型的设计模式,例如装饰器。

下面是String的扩展方法:

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

而生成的扩展方法代码如下Java:

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

所以 Kotlin 中的扩展方法是使用 委托 而不是继承。

然后你可以像下面这样调用一个扩展方法作为它的成员函数:

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

也可以对已有的扩展函数写一个扩展方法,例如:

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

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

但是不能为已有的成员函数写扩展方法,例如:

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

//   v--- return 'a' rather than throws an Exception
val second = "bar"[1]

您可以使用 Kotlin 中的扩展函数来做到这一点。通过扩展,您可以向 class 添加您可以访问或无法访问的额外功能;例如遗留代码库。在 Kotlin 文档 here 中给出的示例中,swap 被添加到原本没有 swapMutableList<Int> 中。 this 关键字用于指代交换功能将对其进行操作的对象。在下面的示例中,this 指的是 testList

val testList = mutableListOf(1, 2, 3)
testList.swap(0, 2)

正在尝试添加更多详细信息,此答案可能对某些人有所帮助。

是的,我们可以向 final 类 添加其他方法,例如 String。例如,我想在 String 中添加一个方法,它会告诉我我的 String 是否具有有效的密码字符数。

所以我要做的是,我创建了一个下面的函数,它可以写在同一个 class 或不同的单独 class 文件中。

    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
    }

现在可以随时随地调用

    val isValid : Boolean = password.haveValidLength()

建议

如果您的应用程序只有一个密码验证,则没有问题。

但是,如果应用程序有多个验证,我不建议您编写这样的扩展方法hasValidPassword。由于扩展方法是 satically,因此您无法在运行时更改 hasValidPassword。所以如果你想在运行时改变验证,你应该使用一个函数来代替,例如:

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")

换句话说,上面的扩展方法违反了Single Responsibility Principle,它进行了验证和字符串操作。