[toc]html
本章將講解一些管對對象和基礎編程的知識。如:類,接口,抽象類,數據類,擴展方法等java
其實這部分的設計思路和Java基本一致。這裏主要說下Kotlin特有的屬性git
abstract class Manager : Driver, Writer {
override fun driver() {
}
override fun writer() {
}
}
interface Driver {
fun driver(){
println("driver")
}
}
class CarDriver : Driver {
override fun driver() {
println("開車")//接口的默認實現
}
}
interface Writer {
fun writer()
}
class PPTWriter : Writer {
override fun writer() {
println("寫PPT")
}
}
class SeniorManager(val driver: Driver, val writer: Writer) : Driver by driver, Writer by writer {//實現忌口可是經過by關鍵字能夠不用去實現裏面的接口方法
}
/**
* 不加by關鍵字那麼就要實現接口的方法
*/
class SeniorManager1(val driver: Driver, val writer: Writer) : Driver, Writer {
override fun driver() {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
override fun writer() {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
}
fun main(args: Array<String>) {
val driver = CarDriver()
val writer = PPTWriter()
val seniorManager = SeniorManager(driver, writer)
seniorManager.driver()
seniorManager.writer()
}
複製代碼
接口是約定,抽象類本是是類的一種:github
abstract class Person(val age: Int) {
open fun work() {
}
}
abstract class Person1(open val age: Int = 3) {
abstract fun work()
}
class MaNong(age: Int) : Person(age) {
override fun work() {
super.work()
println("我是碼農,我在寫代碼")
}
}
class Doctor(age: Int) : Person1(age) {
override val age: Int
get() = 6//5.傳入後又重寫
override fun work() {
println("我是醫生,我給人看病")
}
}
複製代碼
Kotlin | Java |
---|---|
private | private |
protected↑ | protected |
- | default (包內可見) |
internal (模塊Module內可見) | - |
public | public |
例子:編程
interface Listener {
fun start()
fun stop()
}
abstract class Player
object MusicPlayer : Player(), Listener {//能夠實現接口,繼承父類
override fun start() {
}
override fun stop() {
}
val state = 0//能夠有成員屬性
fun continuePlay() {//能夠有方法
}
}
fun main(args: Array<String>) {
val music: MusicPlayer = MusicPlayer//後面沒有括號,也就是說明不是調用構造方法建立的對象
}
複製代碼
kotlin 中時沒有static 這種方法修飾的靜態方法 因此要實現 相似於java中的靜態屬性就要用到伴生對象
例子:bash
fun main(args: Array<String>) {
/**
* 這時候調用伴生對象就至關於調用java靜態方法 格式相同
*/
val value = Latitude.ofDouble(3.0)
println(Latitude.TAG)
}
/**
* 私有的構造方法 companion伴生對象關鍵字
*/
class Latitude private constructor(val latitude: Double) {
companion object {
fun ofDouble(double: Double): Latitude {
return Latitude(double)
}
@JvmStatic//加上這個註解能夠在Java中如static同樣調用
fun ofLatitude(latitude: Latitude): Latitude {
return Latitude(latitude.latitude)
}
@JvmField//加上這個註解能夠在Java中如static同樣調用
val TAG = "Latitude"
}
}
複製代碼
與Java相同,,須要注意一下幾點app
爲現有類添加方法、屬性:ide
例子:函數
//本身定義一個擴展方法 方法的名字是 類型.方法名
fun String.copy(int: Int): String {
val buildStr = StringBuilder()
for (i in 0 until int) {
buildStr.append("abc")
}
return buildStr.toString()
}
//也能夠用操做符
operator fun String.times(int: Int): String {
val buildStr = StringBuilder()
for (i in 0 until int) {
buildStr.append("abc")
}
return buildStr.toString()
}
輸出:
fun main(args: Array<String>) {
println("abc".copy(5))
println("abc" * 5)//操做符 times對應* 具體參照文檔 https://kotlinlang.org/docs/reference/operator-overloading.html
}
複製代碼
代理的場景 好比定義一個屬性外界去訪問,能夠在getValue去讀取一個文件setValue去寫入一個文件那麼就至關於與讀取一個就能夠文件,調用處代碼變得很是簡潔學習
class Delegates4_9 {
val hello by lazy {
//懶加載 只有第一次使用的時候纔回去初始化
"helloWorld"
}
val hello2 by LazyX()//代理 //不可變代理 使用2處代碼
var hello3 by LazyX()//代理
}
class LazyX {
var value: String? = null
//仿寫Lazy 2
// operator fun getValue(thisRef: Any?, property: KProperty<*>): String {
// return "Hello Lazy"
// }
operator fun getValue(thisRef: Any?, property: KProperty<*>): String {
println("getValue: $thisRef ->${property.name}")
return "Hello Lazy"
}
operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {
println("setValue: $thisRef ->${property.name} = $value")
this.value = value
}
}
fun main(args: Array<String>) {
val delegates = Delegates4_9()
println(delegates.hello)
println(delegates.hello2)
println(delegates.hello3)
delegates.hello3 = "value of hello3"
println(delegates.hello3)
}
複製代碼
主要是講解data關鍵字,data主要是幫助生成copy,toString,componentN(對應返回定義的參數) hasCode,equals等方法,默認是沒有無參數的構造方法而且生成的類是final的,須要用allOpen去掉final,noArg建立無參數構造函數
allOpen/noArg:
appModule下build.gradle
apply plugin: 'kotlin-noarg'
apply plugin: 'kotlin-allopen'
noArg {
annotation("packageName.Poko")
}
allOpen {
annotation("packageName.Poko")
}
複製代碼
項目下的build.gradle:
dependencies {
classpath "org.jetbrains.kotlin:kotlin-noarg:1.3.21"
classpath "org.jetbrains.kotlin:kotlin-allopen:1.3.21"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
複製代碼
使用:
@Poko
data class Country4_10(val id: Int, val name: String)
複製代碼
Kotlin的內部類與Java內部類概念相同。存在如下幾種不一樣點:
例子:
class Outter {
val a = 0
class Inner {
fun main(args: Array<String>) {
// println(a)//訪問不到 說明kotlin中默認是使用靜態static內部類的
println(Outter().a)
}
}
inner class Inner1 {
//inner關鍵字 變成非靜態 這樣就能夠訪問到外部類的屬性的
val a = 6
fun main(args: Array<String>) {
// println(a)//訪問不到 說明kotlin中默認是使用靜態static內部類的
println(this@Outter.a)//當內外部類重載相同的屬性或方法時 經過this@Outter訪問
println(this@Inner1.a)
println(a)
}
}
}
interface OnClickListener {
fun click()
}
class View {
var onClickListener: OnClickListener? = null
}
open class Text
fun main(args: Array<String>) {
val view = View()
view.onClickListener = object : Text(), OnClickListener {
//java 匿名內部類是不能繼承的 kotlin能夠
//用object關鍵字來實例化內部類
override fun click() {
}
}
}
複製代碼
基本與Java一致。例子:
enum class LogcatLevel(val id: Int) {
VERBOSE(5), DEBUG(6), INFO(7), WARN(8), ERROR(9), ASSERT(10);//枚舉類能夠定義方法
fun getTag(): String {
return "$name , $id"
}
override fun toString(): String {
return "$name , $ordinal"
}
}
複製代碼
Kotlin枚舉類中定義方法,那麼要在枚舉對象最後加上; 這基本是Kotlin中惟一一個須要強制寫;的地方
記過這4篇文章的學習,基本已經掌握Kotlin的基本語法和對Java的對比,也順帶複習了一下Java的知識,下一篇咱們來學習一些關於Kotlin的高階函數