实现和继承
一、实现接口
在Java中实现接口:
//Clickable.java
public interface Clickable {
void click(); //Java中的接口是一种特殊的抽象类,接口里面的所有方法都是抽象方法
}
//Button.java
public class Button implements Clickable{
@Override
public void click() {
System.out.println(("I am Button, i am clicked"));
}
}
相对应的代码 在Kotlin中实现接口:
//Test33.kt
interface Clickable{
fun click()
}
class Button:Clickable{
override fun click() = println("I am Button, i am clicked")
}
二、继承类
在Java中继承类:
//java
//父类
public class People{
public void say(){
System.out.println("Hello World!");
}
}
//子类
public class men extends People{
}
//main函数
public static void main(String[] args){
men man = new men();
man.say();
}
相对应的代码 在Kotlin中继承类:
//父类
open class People {
fun say() {
println("Hello World!")
}
}
//子类
class men : People()
//main函数
fun main(args: Array<String>) {
val man = men()
man.say()
}
三、Kotlin在 继承父类 和 实现接口 时的特点
(一)继承父类 / 实现接口 的方式
Kotlin使用 冒号 来代替了 Java 中的 extends 和 implements 关键字
(二) 重写 父类/接口 中的方法和属性
Kotlin用 override 修饰符来标注被重写的父类或接口的方法和属性,与Java中的注解 @Override 不同的是,override 修饰符是强制要求 的
(三)调用父类的方法
Kotlin 和 Java 中一样,调用 “super.方法名()”。
但是如果两个父类有同样的方法实现,在子类中调用时,需提供显式实现:
//kotlin
interface Clickable{
fun click()
fun showoff() = println("i am clickable")
}
interface Interfaceaa{
fun click()
fun showoff() = println("i am Interfaceaa")
}
class Button:Clickable,Interfaceaa{
override fun click() = println("I am Button, i am clicked")
override fun showoff(){
super<Clickable>.showoff() //显式地表示调用父类Clickable的方法。在Java中对应的是Clickable.super.showOff()
super<Interfaceaa>.showoff() //显式地表示调用父类Interfaceaa的方法
}
}
(四)open 修饰符 & 创建子类
在Kotlin中:
接口、接口方法、抽象类默认为 open
父类需要 open 才可被继承,父类的方法和属性需要 open 才可被重写
Java允许创建任意类的子类并重写任意方法,除非该类显式地使用 final 关键字进行标注
但是这样的话,一旦修改基类,子类可能出现预期之外的行为改变
《Effective Java》的作者建议"要么为继承做好设计并记录文档,要么禁止这么做"
所以,所有的没有特别需要在子类中被重写的类和方法应该被显式地标注为 final
Kotlin中的类和方法默认都是final的
Kotlin中,如果想要允许创建一个类的子类,需要使用 open 修饰符来标示这个类;如果想要某个属性或方法可以被重写,需要使用open修饰符来标示这个属性或方法。
例:声明一个可被继承的类:
open class Button:Clickable{
fun disable(){} //默认为final,不可被子类重写
open fun animate(){} //open,可以在子类中重写
override fun click(){} //重写了一个open函数,并且它本身也是open的,即可以在子类中重写。如果想要阻止本类的子类重写此实现,可以显式地将重写的成员标注为 final,如下行代码
//final override fun click(){}
}
(六)超类Any
在 Kotlin 中所有类都有一个共同的超类 Any(不同于Object),这对于没有声明超类型的类提供了默认的超类。Any 类默认提供了三个方法:equal()、hashCode()、toString()
(七)类委托(接口代理)
类委托 和 数据类 可以由编译器生成方法
Kotlin提供了类委托(接口代理),将接口方法实现直接交给代理类实现
Kotlin 中利用 by 关键字,将新类的接口实现委托给原始类对象,编译器会为新类自动生成接口方法,并默认返回原始类对应的具体实现。
使用 by关键字 之前:
class MySet<T>(val helperSet: HashSet<T>) : Set<T> {
override val size: Int
get() = helperSet.size
override fun contains(element: T) = helperSet.contains(element)
override fun containsAll(elements: Collection<T>) = helperSet.containsAll(elements)
override fun isEmpty() = helperSet.isEmpty()
override fun iterator() = helperSet.iterator()
fun helloWorld() = println("Hello World") //添加自己的方法
}
fun main(args:Array<String>){
val set = hashSetOf<Int>(1,2,3)
val mySet = MySet(set)
mySet.helloWorld()
}
使用 by关键字 之后:
class MySet<T>(val helperSet: HashSet<T>) : Set<T> by helperSet {
fun helloWorld() = println("Hello World")
override fun isEmpty() = false
}
fun main(args:Array<String>){
val set = hashSetOf<Int>(1,2,3)
val mySet = MySet(set)
mySet.helloWorld()
}
————————————————
版权声明:本文为CSDN博主「浅唱整个春天」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_32677531/article/details/126079620