定義一個Person類java
class Person{
}
複製代碼
在Expand.kt文件定義Person類擴展函數bash
fun Person.name(name: String) {
println(name)
}
fun Person.age(age: String) = println(age)
複製代碼
kotlin使用擴展函數ide
val person = Person()
person.name("zhang")
person.age("97")
複製代碼
java使用擴展函數函數
Person person = new Person();
ExpandKt.name(person,"zhang");
ExpandKt.age(person,"97");
複製代碼
擴展函數支持多態嗎?佈局
擴展函數是靜態添加的,不具備運行時的多態效應優化
open class Animal
class Dog : Animal()
fun Animal.name(): String = "animal"
fun Dog.name(): String = "dog"
fun Animal.printName(animal: Animal) {
println(animal.name())
}
fun main() {
val dog = Dog()
dog.printName(dog)
}
複製代碼
轉爲java,會強轉爲Animal,因此不支持多態ui
public static final void main() {
Dog dog = new Dog();
printName((Animal)dog, (Animal)dog);
}
複製代碼
// lambda寫法
var say = { name: String, age: Int ->
println("my name is $name,and I am $age")
}
// 函數寫法
fun say1(name: String, age: Int): Unit {
println("my name is $name,and I am $age")
}
fun main() {
say("zhang", 97)
say1("zhang", 97)
}
複製代碼
my name is zhang,and I am 97this
my name is zhang,and I am 97spa
var sayMany = { p1: String, p2: String, p3: String,
p4: String, p5: String, p6: String, p7: String, p8: String, p9: String, p10: String, p11: String, p12: String,
p13: String, p14: String, p15: String, p16: String, p17: String, p18: String, p19: String, p20: String, p21: String,
p22: String//若是這裏有p23:String,會報錯說沒有Function23
->
println("my name is $p1")
}
sayMany("a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a")
複製代碼
my name is a3d
新版本kotlin解決了這個問題,個人的這個版本參數是能夠超越22的,緣由以下
var sayMany = { p1: String, p2: String, p3: String,
p4: String, p5: String, p6: String, p7: String, p8: String, p9: String, p10: String, p11: String, p12: String,
p13: String, p14: String, p15: String, p16: String, p17: String, p18: String, p19: String, p20: String, p21: String,
p22: String, p23: String, p24: String
->
println("my name is $p1")
}
複製代碼
轉爲java
static {
say = (Function2)null.INSTANCE;//兩個參數的
sayMany = (FunctionN)null.INSTANCE;//22參數以上的
}
複製代碼
// 高階函數,參數或者返回值,是一個函數(或者Lambda)
fun onlyif(isDebug: Boolean, block: () -> Unit) {
if (isDebug) {
block()
}
}
fun main() {
onlyif(true) { println("打印日誌") }
}
複製代碼
// 1. 定義一個runnable對象
val runnable = Runnable {
println("Runnable::run 這是一個函數引用 ::")
}
// 2. 聲明一個函數叫作 function,這個函數類型是 ()->Unit
val function: () -> Unit
// 3. 如今要給function這個函數賦值,這個值必須也是一個函數,而且類型也是()->Unit
// function = runnable.run()//不能這樣寫,runnable.run()表示把執行結果賦值給了function
function = runnable::run//這就對了,把函數的引用賦值給function
onlyif(true, function)
複製代碼
Runnable::run 這是一個函數引用 ::
對比下面的代碼,區別只是在高階函數onlyif以前加了一個inline
inline fun onlyif(isDebug: Boolean, block: () -> Unit) {
if (isDebug) {
block()
}
}
fun main() {
onlyif(true) { println("打印日誌") }
}
複製代碼
fun onlyif1(isDebug: Boolean, block: () -> Unit) {
if (isDebug) {
block()
}
}
fun main() {
onlyif1(true) { println("打印日誌") }
}
複製代碼
可是不建議處處使用inline,通常只是在高級函數前面使用,用他的目的是爲了減小沒必要要的由Lambda表達式帶來的匿名對象 過分使用inline會給編譯器帶來負擔,查找問題變得複雜,不建議亂用這inline
寫在類聲明的地方
open class Person(name: String)
class Man(name: String) : Person(name){
init {
println("構造函數執行時,我會執行的 $name")
}
}
fun main() {
Man("zhang")
}
複製代碼
若是由多個構造函數,第二個構造函數經過次構造函數實現,寫到類內部
次構造函數,必須直接或間接調用該類主構造函數,或者改類的父類構造函數
open class Person(name: String)
class Man(name: String) : Person(name) {
private var age: Int = 0
private var address: String = ""
init {
println("構造函數執行時,我會執行的 $name")
}
constructor(name: String, age: Int) : this(name) {
this.age = age
}
constructor(name: String, age: Int, address: String) : this(name,age) {
this.address = address
}
}
fun main() {
Man("zhang")
Man("zhang", 97)
Man("zhang", 97, "beijng")
}
複製代碼
相似java靜態
class StringUtils{
companion object{
fun isEmpty(str: String): Boolean {
return str.isEmpty()
}
}
}
fun main() {
val empty = StringUtils.isEmpty("")
}
複製代碼
若是java裏想像靜態同樣使用這個伴生對象方法,要加上@Jvmstatic
class StringUtils {
companion object {
@JvmStatic
fun isEmpty(str: String): Boolean {
return str.isEmpty()
}
}
複製代碼
public class JavaC {
public static void main(String[] args) {
StringUtils.isEmpty("str");
}
}
複製代碼
固然直接使用object也行
class Single private constructor() {
companion object {
fun get(): Single {
return Holder.instance
}
}
private object Holder {
val instance = Single()
}
}
複製代碼
java 的寫法是很繁瑣的
interface Drive {
fun driving()
}
class MiShu : Drive {
override fun driving() {
println("我是祕書,我在開車。。。")
}
}
// Manager代理類,Mishu被代理類,他們都實現Drive接口
// 經理本身不用實現開車方法,,他是用的是祕書的開車方法
class Manager(drive: Drive) : Drive by drive {
}
fun main() {
Manager(MiShu()).driving()
}
複製代碼
我是祕書,我在開車。。。
interface Drive {
fun driving()
}
class MiShu : Drive {
override fun driving() {
println("我是祕書,我在開車。。。")
}
}
// Manager代理類,Mishu被代理類,他們都實現Drive接口
//一旦經理本身實現了開車方法,那麼就是經歷本身開車了
class Manager(drive: Drive) : Drive by drive {
override fun driving() {
println("我是經理,我在開車。。。")
}
}
fun main() {
Manager(MiShu()).driving()
}
複製代碼
我是經理,我在開車。。。