亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

解決Kotlin 類(lèi)在實(shí)現(xiàn)多個(gè)接口,覆寫(xiě)多個(gè)接口中相同方法沖突的問(wèn)題

 更新時(shí)間:2020年03月16日 12:33:24   作者:向小凱同學(xué)學(xué)習(xí)  
這篇文章主要介紹了解決Kotlin 類(lèi)在實(shí)現(xiàn)多個(gè)接口,覆寫(xiě)多個(gè)接口中相同方法沖突的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧

一、首先來(lái)看一個(gè)例子

package net.println.kotlin.chapter4

/**
 * @author:wangdong
 * @description:類(lèi)實(shí)現(xiàn)接口的沖突問(wèn)題
 */

interface B{
  fun x(): Int = 1
}

interface C{
  fun x(): Int = 0
}

/**一個(gè)類(lèi)實(shí)現(xiàn)了兩個(gè)接口,兩個(gè)接口中的方法相同,這個(gè)類(lèi)在覆寫(xiě)的時(shí)候就會(huì)出現(xiàn)沖突*/
class D: B,C{
  //當(dāng)下面兩個(gè)方法同時(shí)存在的時(shí)候,就會(huì)報(bào)方法相同的沖突
  override fun x(): Int {
    return super<B>.x()
  }

  override fun x(): Int {
    return super<C>.x()
  }
}

二、解決沖突的例子

package net.println.kotlin.chapter4

/**
 * @author:wangdong
 * @description:類(lèi)繼承類(lèi),實(shí)現(xiàn)接口的方法沖突問(wèn)題
 * 接口方法可以有默認(rèn)的實(shí)現(xiàn)
 * 簽名一致且返回值相同的沖突
 * 子類(lèi)(實(shí)現(xiàn)類(lèi))必須覆寫(xiě)沖突方法
 * super<[父類(lèi)(接口)名]>.[方法名]([參數(shù)列表])
 */

abstract class A{
  open fun x(): Int = 5
}

interface B{
  fun x(): Int = 1
}

interface C{
  fun x(): Int = 0
}

/**一個(gè)類(lèi)實(shí)現(xiàn)了兩個(gè)接口,兩個(gè)接口中的方法相同,這個(gè)類(lèi)在覆寫(xiě)的時(shí)候就會(huì)出現(xiàn)沖突*/
/**采用分支模式解決沖突問(wèn)題*/
class D(var y: Int = 0):A() ,B,C{

  //返回值一定要一樣啊,例如:一定要是Int
  override fun x(): Int {
    println("call x(): Int in D")
    if (y > 0){
      return y
    }else if (y < -200){
      return super<C>.x()
    }else if (y < -100){
      return super<B>.x()
    }else{
      return super<A>.x()
    }
  }
}

fun main(args: Array<String>) {
  println(D(3).x())
  println(D(-10).x())
  println(D(-110).x())
  println(D(-230).x())
}
/**輸出的結(jié)果*/
call x(): Int in D

call x(): Int in D

call x(): Int in D

call x(): Int in D

補(bǔ)充知識(shí):Kotlin 如何優(yōu)雅的實(shí)現(xiàn)『多繼承』

這一期給大家講一個(gè)有意思的東西。我們都知道 Java 當(dāng)年高調(diào)的調(diào)戲 C++ 的時(shí)候,除了最?lèi)?ài)說(shuō)的內(nèi)存自動(dòng)回收之外,還有一個(gè)著名的單繼承,任何 Java 類(lèi)都是 Object 的子類(lèi),任何 Java 類(lèi)有且只有一個(gè)父類(lèi),不過(guò),它們可以有多個(gè)接口,就像這樣:

public class Java extends Language 
  implements JVMRunnable{  
  ...
}

public class Kotlin extends Language 
  implements JVMRunnable, FERunnable{  
  ...
}

這樣用起來(lái)真的比 C++ 要簡(jiǎn)單得多,不過(guò)有時(shí)候也會(huì)有些麻煩:Java 和 Kotlin 都可以運(yùn)行在 JVM 上面,我們用一個(gè)接口 JVMRunnable 來(lái)標(biāo)識(shí)它們的這一身份;現(xiàn)在我們假設(shè)這二者對(duì)于 JVMRunnable 接口的實(shí)現(xiàn)都是一樣的,所以我們將會(huì)在 Java 和 Kotlin 當(dāng)中寫(xiě)下兩段重復(fù)的代碼:

public class Java extends Language 
  implements JVMRunnable{  
  public void runOnJVM(){    
    ...
  }
}

public class Kotlin extends Language 
  implements JVMRunnable, FERunnable{  
  public void runOnJVM(){    
    ...
  }  
  
  public void runOnFE(){    
    ...
  }
}

重復(fù)代碼使我們最不愿意看到的,所以我們決定創(chuàng)建一個(gè) JVMLanguage 作為 Java 和 Kotlin 的父類(lèi),它提供默認(rèn)的 runOnJVM 的實(shí)現(xiàn)。看上去挺不錯(cuò)。

public abstract class JVMLanguage{  
  public void runOnJVM(){    
    ...
  }
}
    
public class Java extends JVMLanguage{

}

public class Kotlin extends JVMLanguage 
  implements FERunnable{  
  
  public void runOnFE(){    
    ...
  }
}

當(dāng)然,我們還知道 Kotlin 可以編譯成 Js 運(yùn)行,那我們硬生生的把 Kotlin 稱(chēng)作 JVMLanguage 就有些牽強(qiáng)了,而剛剛我們覺(jué)得很完美的寫(xiě)法呢,其實(shí)是不合適的。

簡(jiǎn)單的說(shuō),繼承和實(shí)現(xiàn)接口的區(qū)別就是:繼承描述的是這個(gè)類(lèi)『是什么』的問(wèn)題,而實(shí)現(xiàn)的接口則描述的是這個(gè)類(lèi)『能做什么』的問(wèn)題。

Kotlin 與 Java 在能夠運(yùn)行在 JVM 這個(gè)問(wèn)題上是一致的,可 Java 卻不能像 Kotlin 那樣去運(yùn)行在前端,Kotlin 和 Java 運(yùn)行在 JVM 上這個(gè)點(diǎn)只能算作一種能力,而不能對(duì)其本質(zhì)定性。

于是我們?cè)?Java 8 當(dāng)中看到了接口默認(rèn)實(shí)現(xiàn)的 Feature,于是我們的代碼可以改改了:

public interface JVMRunnable{
  default void runOnJVM(){    
    ...
  }
}
    
public class Java extends Language 
  implements JVMRunnable{

}
  
public class Kotlin extends Language 
  implements JVMRunnable, FERunnable{  
  public void runOnFE(){    
    ...
  }
}

這樣很好,不過(guò),由于接口無(wú)法保存狀態(tài),runOnJVM 這個(gè)方法的接口級(jí)默認(rèn)實(shí)現(xiàn)仍然非常受限制。

那么 Kotlin 給我們帶來(lái)什么呢?大家請(qǐng)看下面的代碼:

abstract class Languageinterface JVMRunnable{  
  fun runOnJVM()
}

class DefaultJVMRunnable : JVMRunnable {  
  override fun runOnJVM() {
    println("running on JVM!")
  }
}

class Java(jvmRunnable: JVMRunnable) 
  : Language(), JVMRunnable by jvmRunnable

class Kotlin(jvmRunnable: JVMRunnable) 
  : Language(), JVMRunnable by jvmRunnable, FERunnable{  
  fun runOnFE(){    
    ...
  }
}

通過(guò)接口代理的方式,我們把 JVMRunnable 的具體實(shí)現(xiàn)代理給了 jvmRunnable 這個(gè)實(shí)例,這個(gè)實(shí)例當(dāng)然是可以保存狀態(tài)的,它一方面可以很好地解決我們前面提到的接口默認(rèn)實(shí)現(xiàn)的問(wèn)題,另一方面也能在提供能力的同時(shí)不影響原有類(lèi)的『本質(zhì)』。

以上這篇解決Kotlin 類(lèi)在實(shí)現(xiàn)多個(gè)接口,覆寫(xiě)多個(gè)接口中相同方法沖突的問(wèn)題就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論