一手遮天 Android - kotlin: 类相关 2(类继承,接口,抽象类,by 委托)
一手遮天 Android - 类相关 2(类继承,接口,抽象类,by 委托)
示例如下:
/kotlin/Demo8.kt
/**
* 本例用于演示类继承,接口,抽象类,by 委托
*/
package com.webabcd.androiddemo.kotlin
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import com.webabcd.androiddemo.R
import kotlinx.android.synthetic.main.activity_kotlin_helloworld.*
import kotlin.reflect.KProperty
class Demo8 : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_kotlin_demo8)
sample1() // 类继承
sample2() // 接口
sample3() // 抽象类
sample4() // by 委托
}
fun sample1() {
var a = Demo8_Class1(40);
appendMessage(a.hello()) // hello:wanglei, age:40, country:china
var b = Demo8_Class2(40, "中国");
appendMessage(b.hello()) // hi:wanglei, age:80, country:中国
}
fun sample2() {
var a = Demo8_Class3(40)
appendMessage(a.hello()) // hello:wanglei, age:40 hi:wanglei, age:40
}
fun sample3() {
var a = Demo8_Class4("wanglei")
appendMessage(a.hello()) // hello:wanglei, age:100, country:china
}
fun sample4() {
// 接口的实现委托给指定的参数(通过 by 委托)
var a = MyClass1("webabcd")
var b = MyClass2(a)
appendMessage("${a.hello()}, ${b.hello()}") // hello: webabcd, hello: webabcd
// 属性的实现委托给指定的类(通过 by 委托)
var c = MyClass3()
c.myName = "webabcd"
appendMessage("${c.myName}") // property name:myName, value:webabcd
// 注:还有一种 by 委托可以用来实现属性的懒初始化,即 by lazy(请参见:Demo1.kt)
}
interface MyInterface {
fun hello(): String
}
class MyClass1(val name: String): MyInterface {
override fun hello(): String {
return "hello: $name"
}
}
// MyClass2 类委托 xxx 参数实现 MyInterface 接口
// 也就是说 MyClass2 类实现了 MyInterface 接口,你在调用 MyClass2 的相关实现的时候,其实调用的是 xxx 的实现
class MyClass2(xxx: MyInterface): MyInterface by xxx {
// 如果你在这里实现 MyInterface 接口的某些方法的话,则这里的实现会覆盖 xxx 的实现
}
// myName 属性的实现委托给 MyDelegate 类
class MyClass3 {
var myName: String by MyDelegate()
}
class MyDelegate {
private var _s: String = ""
operator fun getValue(thisRef: Any?, property: KProperty<*>): String {
return "property name:${property.name}, value:$_s"
}
operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {
_s = value
}
}
fun appendMessage(message: String) {
textView1.append(message)
textView1.append("\n")
}
}
\kotlin\Demo8_Class1.kt
/**
* 父类(用于演示类继承)
*
* 可被继承的类要用 open 修饰(默认是 final 的,即不可继承)
* 可被重写的属性或方法要用 open 修饰(默认是 final 的,即不可重写)
*/
package com.webabcd.androiddemo.kotlin
open class Demo8_Class1(var age: Int) {
init {
this.age = age
}
open var name = "wanglei"
open var country = "china"
open fun hello(): String {
return "hello:$name, age:$age, country:$country"
}
}
\kotlin\Demo8_Class2.kt
/**
* 子类(用于演示类继承)
*/
package com.webabcd.androiddemo.kotlin
// 通过 : 继承父类,调用父类的主构造函数
// 通过类似如下 override var country: String 的方式重写父类的属性
// 注:这个类也可以被继承,因为他用 open 修饰了,如果需要这个类不可以被继承,就把 open 去掉,那么就是默认 final 了,就不能被继承了
open class Demo8_Class2(age: Int, override var country: String) : Demo8_Class1(age * 2) {
// 如下方式,通过 super 调用非主构造函数
// constructor(country: String): super(country)
// 属性在父类中是 val,那么是可以在子类中改用 var 修饰的
// 属性在父类中是 var,那么是不能在子类中改用 val 修饰的
// 重写属性
// 注:父类中 name 是 open 的,所以如果某个类继承了这个类,那么其是可以重写此属性的,如果不想这样,那么这里就要用 final 修饰,类似这样 final override var name...
override var name = "wanglei"
// 重写方法
// 注:父类中 hello() 是 open 的,所以如果某个类继承了这个类,那么其是可以重写此方法的,如果不想这样,那么这里就要用 final 修饰,类似这样 final override fun hello(): String...
override fun hello(): String {
// 通过 super 调用父类的属性或方法
// super.name
// super.hello()
return "hi:$name, age:$age, country:$country"
}
}
\kotlin\Demo8_Class3.kt
/**
* 实现类(用于演示接口)
*
* 接口的方法可以有自己的实现,但是属性不可以有自己的实现(需要子类实现)
*/
package com.webabcd.androiddemo.kotlin
// 通过 : 实现多个接口
// 通过类似如下 override var age: Int 的方式实现接口的属性
class Demo8_Class3(override var age: Int) : Demo8_Interface1, Demo8_Interface2 {
init {
this.age = age;
}
// 实现接口的属性
override var name: String = ""
get() = "wanglei"
// 实现接口的方法
override fun hello(): String {
// 通过 super 调用接口的方法
// super.hello()
// 如果实现的多个接口有重名的方法,则可以用如下方式调用不同接口的方法
return super<Demo8_Interface1>.hello() + " " + super<Demo8_Interface2>.hello()
}
}
\kotlin\Demo8_Interface1.kt
/**
* 接口 1(用于演示接口)
*
* 接口的方法可以有自己的实现,但是属性不可以有自己的实现(需要子类实现)
*/
package com.webabcd.androiddemo.kotlin
interface Demo8_Interface1 {
var name: String
var age: Int
fun hello(): String {
return "hello:$name, age:$age"
}
}
\kotlin\Demo8_Interface2.kt
/**
* 接口 2(用于演示接口)
*
* 接口的方法可以有自己的实现,但是属性不可以有自己的实现(需要子类实现)
*/
package com.webabcd.androiddemo.kotlin
interface Demo8_Interface2 {
var name: String
var age: Int
fun hello(): String {
return "hi:$name, age:$age"
}
}
\kotlin\Demo8_Class4.kt
/**
* 子类(用于演示抽象类)
*/
package com.webabcd.androiddemo.kotlin
// 通过 : 继承抽象类
// 通过类似如下 override var name: String 的方式重写抽象类的抽象属性
class Demo8_Class4(override var name: String) : Demo8_Abstract() {
init {
this.name = name
}
// 重写抽象类的抽象属性
override var country = "china"
// 重写抽象类的抽象方法
override fun getAge(): Int {
return 100;
}
}
\kotlin\Demo8_Abstract.kt
/**
* 抽象类(用于演示抽象类)
*/
package com.webabcd.androiddemo.kotlin
abstract class Demo8_Abstract {
// 需要子类重写的属性
abstract var name:String
// 需要子类重写的属性
abstract var country:String
// 需要子类重写的方法
abstract fun getAge(): Int
// 有自己逻辑的方法,不需要子类重写
fun hello(): String {
return "hello:$name, age:${getAge()}, country:$country"
}
}
/layout/activity_kotlin_demo8.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>