Kotlin中的對象表達(dá)式和對象聲明的具體使用
Kotlin的對象表達(dá)式與Java中的匿名內(nèi)部類的主要區(qū)別:匿名內(nèi)部類只能指定一個父類型,但對象表達(dá)式可以指定0~N個膚類型。
一、對象表達(dá)式
對象表達(dá)式的語法格式如下:
object [: 0~N個父類型]{
//對象表達(dá)式的類體部分
}
對象表達(dá)式還有如下規(guī)則:
- 對象表達(dá)式不能是抽象類,因?yàn)橄到y(tǒng)在創(chuàng)建對象表達(dá)式時會立即創(chuàng)建對象。因此不允許將對象表達(dá)式定義成抽象類。
- 對象表達(dá)式不能定義構(gòu)造器。但對象表達(dá)式可以定義初始化塊,可以通過初始化塊來完成構(gòu)造器需要完成的事情。
- 對象表達(dá)式可以包含內(nèi)部類,不能包含嵌套類。
package `0705`
interface Outputable {
fun output(msg: String)
}
abstract class Product(var price: Double) {
abstract val name: String
abstract fun printInfo()
}
fun main(args: Array<String>) {
//指定一個父類型(接口)的對象表達(dá)式
var ob1 = object : Outputable {
override fun output(msg: String) {
for (i in 1..6) {
println("<h${i}>${msg}</h${i}>")
}
}
}
ob1.output("隨便輸出點(diǎn)什么吧")
println("-----------------------------------------------")
//指定零個父類型的對象表達(dá)式
var ob2 = object {
//初始化塊
init {
println("初始化塊")
}
//屬性
var name = "Kotlin"
//方法
fun test() {
println("test方法")
}
//只能包含內(nèi)部類,不可以包含嵌套類
inner class Inner
}
println(ob2.name)
ob2.test()
println("-----------------------------------------------")
//指定兩個父類型的對象表達(dá)式
var ob3 = object : Outputable, Product(1.23) {
override fun output(msg: String) {
println("輸出信息:${msg}")
}
override val name: String
get() = "激光打印機(jī)"
override fun printInfo() {
println("高速極光打印機(jī)們支持自動雙面打??!")
}
}
println(ob3.name)
ob3.output("Kotlin慢慢學(xué)")
ob3.printInfo()
}
輸出結(jié)果:
<h1>隨便輸出點(diǎn)什么吧</h1>
<h2>隨便輸出點(diǎn)什么吧</h2>
<h3>隨便輸出點(diǎn)什么吧</h3>
<h4>隨便輸出點(diǎn)什么吧</h4>
<h5>隨便輸出點(diǎn)什么吧</h5>
<h6>隨便輸出點(diǎn)什么吧</h6>
-----------------------------------------------
初始化塊
Kotlin
test方法
-----------------------------------------------
激光打印機(jī)
輸出信息:Kotlin慢慢學(xué)
高速極光打印機(jī)們支持自動雙面打印!
Kotlin的對象表達(dá)式可分為兩種情形:
- 對象表達(dá)式在方法的局部范圍內(nèi),或使用private修飾的對象表達(dá)式,Kotlin編譯器可識別對象表達(dá)式的真實(shí)類型。
- 非private修飾的對象表達(dá)式與Java的匿名內(nèi)部類相似,編譯器只會把對象表達(dá)式當(dāng)成它所繼承的父類或所實(shí)現(xiàn)的接口處理。如果它沒有父類型,系統(tǒng)當(dāng)它是Any類型。
package `0705`
class ObjectExprType {
private val ob1 = object {
val name: String = "Kotlin"
}
internal val ob2 = object {
val name: String = "Kotlin"
}
private fun privateBar()=object {
val name:String="Java"
}
fun publicBar()=object {
val name:String="Java"
}
fun test(){
//ob1是private對象表達(dá)式,編譯器可識別它的真實(shí)類型
println(ob1.name)
//ob2是非private對象表達(dá)式,編譯器當(dāng)它是Any類型
// println(ob2.name)
//privateBar是private函數(shù),編譯器可識別它返回的對象表達(dá)式的真實(shí)類型
println(privateBar().name)
//publicBar是非private函數(shù),編譯器將它返回的對象表達(dá)式當(dāng)成Any類型
// println(publicBar().name)
}
}
fun main(args: Array<String>) {
ObjectExprType().test()
}
輸出結(jié)果:
Kotlin
Java
Kotlin編譯器可以識別private對象表達(dá)式的真實(shí)類型。
Kotlin的對象表達(dá)式可訪問或修飾其作用域內(nèi)的局部變量。
fun main(args: Array<String>) {
var a = 20
var obj = object {
fun change() {
println("change()方法修改變量a的值")
a++
}
}
obj.change()
println(a)
}
輸出結(jié)果:
change()方法修改變量a的值
21
Kotlin的對象表達(dá)式比Java的匿名內(nèi)部類增強(qiáng)了三個方面:
- 對象表達(dá)式可指定多個父類型
- Kotlin編譯器能更準(zhǔn)確地識別局部范圍內(nèi)private對象表達(dá)式的類型。
- 對象表達(dá)式可訪問或修改其所在范圍內(nèi)的局部變量
二、對象聲明和單例模式
對象聲明的語法格式如下:
object ObjectName [: 0~N個父類型]{
//對象表達(dá)式的類體部分
}
對象聲明與對象表達(dá)式的語法很相似,區(qū)別在于:對象表達(dá)式在object關(guān)鍵字后沒有名字;而對象聲明需要在object關(guān)鍵字后指定名字。
兩者還有如下區(qū)別:
- 對象表達(dá)式是一個表達(dá)式,可以被賦值給變量;而對象聲明不是表達(dá)式,不能用于賦值。
- 對象聲明可包含嵌套類,不能包含內(nèi)部類;而對象表達(dá)式可包含內(nèi)部類,不能包含嵌套類。
- 對象聲明不能定義在函數(shù)和方法內(nèi);但對象表達(dá)式可嵌套在其他對象聲明或非內(nèi)部類中。
package `0705`
interface Outputable {
fun output(msg: String)
}
abstract class Product(var price: Double) {
abstract val name: String
abstract fun printInfo()
}
//指定一個父類型的對象表達(dá)式
object MyObject1 : Outputable {
override fun output(msg: String) {
for (i in 1..6) {
println("<h${i}>${msg}</h${i}>")
}
}
}
//指定零個父類型的對象表達(dá)式
object MyObject2 {
//初始化塊
init {
println("初始化塊")
}
//屬性
var name = "Kotlin"
//方法
fun test() {
println("test方法")
}
//只能包含嵌套類,不可以包含內(nèi)部類
class Inner
}
//指定兩個父類型的對象表達(dá)式
object MyObject3 : Outputable, Product(1.23) {
override fun output(msg: String) {
println("輸出信息:${msg}")
}
override val name: String
get() = "激光打印機(jī)"
override fun printInfo() {
println("高速極光打印機(jī)們支持自動雙面打印!")
}
}
fun main(args: Array<String>) {
MyObject1.output("一起來學(xué)Kotlin")
println("-----------------------------------------------")
println(MyObject2.name)
MyObject2.test()
println("-----------------------------------------------")
println(MyObject3.name)
MyObject3.output("Kotlin真不錯")
MyObject3.printInfo()
}
輸出結(jié)果:
<h1>一起來學(xué)Kotlin</h1>
<h2>一起來學(xué)Kotlin</h2>
<h3>一起來學(xué)Kotlin</h3>
<h4>一起來學(xué)Kotlin</h4>
<h5>一起來學(xué)Kotlin</h5>
<h6>一起來學(xué)Kotlin</h6>
-----------------------------------------------
初始化塊
Kotlin
test方法
-----------------------------------------------
激光打印機(jī)
輸出信息:Kotlin真不錯
高速極光打印機(jī)們支持自動雙面打??!
對象聲明專門用于實(shí)現(xiàn)單例模式,對象聲明所定義的對象也就是該類的唯一實(shí)例,程序可通過對象聲明的名稱直接訪問該類的唯一實(shí)例。
三、伴生對象和靜態(tài)成員
在類中定義的對象聲明,可使用companion修飾,這樣該對象就變成了伴生對象。
每個類最多只能定義一個伴生對象,伴生對象相當(dāng)于外部類的對象,程序可通過外部類直接調(diào)用伴生對象的成員。
package `0705`
interface CompanionTest {
fun output(msg: String)
}
class MyClass {
//使用companion修飾的伴生對象
companion object MyObject1 : CompanionTest {
val name = "name屬性值"
override fun output(msg: String) {
for (i in 1..6) {
println("<h${i}>${msg}</h${i}>")
}
}
}
}
fun main(args: Array<String>) {
//使用伴生對象所在的類調(diào)用伴生對象的方法
MyClass.output("Kotlin必須學(xué)")
println(MyClass.name)
}
輸出結(jié)果:
<h1>Kotlin必須學(xué)</h1>
<h2>Kotlin必須學(xué)</h2>
<h3>Kotlin必須學(xué)</h3>
<h4>Kotlin必須學(xué)</h4>
<h5>Kotlin必須學(xué)</h5>
<h6>Kotlin必須學(xué)</h6>
name屬性值
伴生對象的主要作用就是為其所在的外部類模擬靜態(tài)成員,但只是模擬,伴生對象的成員依然是伴生對象本身的實(shí)例成員,并不屬于伴生對象所在的外部類。
四、伴生對象的擴(kuò)展
伴生對象也可以被擴(kuò)展。如果一個類具有伴生對象,則Kotlin允許為伴生對象擴(kuò)展方法和屬性。
package `0705`
interface CompanionTest {
fun output(msg: String)
}
class MyClass {
//使用companion修飾的伴生對象
companion object : CompanionTest {
val name = "name屬性值"
override fun output(msg: String) {
for (i in 1..6) {
println("<h${i}>${msg}</h${i}>")
}
}
}
}
//為伴生對象擴(kuò)展方法
fun MyClass.Companion.test() {
println("為伴生對象擴(kuò)展的方法")
}
val MyClass.Companion.foo
get() = "為伴生對象擴(kuò)展的屬性"
fun main(args: Array<String>) {
//使用伴生對象所在的類調(diào)用伴生對象的方法
MyClass.output("Kotlin必須學(xué)")
println(MyClass.name)
//通過伴生對象所在的類調(diào)用為伴生對象擴(kuò)展的成員
MyClass.test()
println(MyClass.foo)
}
輸出結(jié)果:
<h1>Kotlin必須學(xué)</h1>
<h2>Kotlin必須學(xué)</h2>
<h3>Kotlin必須學(xué)</h3>
<h4>Kotlin必須學(xué)</h4>
<h5>Kotlin必須學(xué)</h5>
<h6>Kotlin必須學(xué)</h6>
name屬性值
為伴生對象擴(kuò)展的方法
為伴生對象擴(kuò)展的屬性
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
基于Android實(shí)現(xiàn)百度地圖定位過程詳解
這篇文章主要介紹了基于Android實(shí)現(xiàn)百度地圖定位過程詳解,需要的朋友可以參考下2015-11-11
Android給scrollView截圖超過屏幕大小形成長圖
這篇文章主要為大家詳細(xì)介紹了Android給scrollView截圖超過屏幕大小形成長圖,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-12-12
Kotlin中空判斷與問號和感嘆號標(biāo)識符使用方法
最近使用kotlin重構(gòu)項(xiàng)目,遇到了一個小問題,在Java中,可能會遇到判斷某個對象是否為空,為空執(zhí)行一段邏輯,不為空執(zhí)行另外一段邏輯,下面這篇文章主要給大家介紹了關(guān)于Kotlin中空判斷與問號和感嘆號標(biāo)識符處理操作的相關(guān)資料,需要的朋友可以參考下2022-12-12
Android自定義TextView實(shí)現(xiàn)文字圖片居中顯示的方法
下面小編就為大家分享一篇Android自定義TextView實(shí)現(xiàn)文字圖片居中顯示的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-01-01
android 中win10 使用uwp控件實(shí)現(xiàn)進(jìn)度條Marquez效果
這篇文章主要介紹了android 中win10 使用uwp控件實(shí)現(xiàn)進(jìn)度條Marquez效果,需要的朋友可以參考下2017-06-06
Android使用Intent隱式實(shí)現(xiàn)頁面跳轉(zhuǎn)
這篇文章主要為大家詳細(xì)介紹了Android使用Intent隱式來實(shí)現(xiàn)向上跳轉(zhuǎn),具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-08-08
Android 照相機(jī)的實(shí)例應(yīng)用
這篇文章主要介紹了Android 照相機(jī)的實(shí)例應(yīng)用的相關(guān)資料,希望通過此文能掌握Android照相機(jī)的使用方法,需要的朋友可以參考下2017-08-08

