含有抽象函数、用abstract来修饰的的类成为抽象类。
举个例子:
abstract class Preson(var name:String,var age:Int){
abstract var weight
abstract var gender
abstract fun doJob()
open fun eat(){
pringln("急头白脸一顿吃")
}
}
absrtact fun doJob()就是抽象方法 abstract var weight、abstract var gender 就是抽象属性
在抽象类里面有具体实现的函数默认是final的,不能被重写。若想被重写需要加open关键字。抽象方法默认是open修饰
来看看具体类的实现
abstract class Student(var name:String, var age:Int): Person(name, age){
override var weight = "50kg"
override var gender = "老爷们一个"
override fun doJob(){
println("苦逼的学习 敲代码")
}
override fun eat(){
super.eat()
println("吃的都是食堂 没啥好的")
}
}
当然了抽象类不能private 不能被子类继承还玩个毛线抽象,用法上跟Java还是很类似的
接口用interface作为关键字,基本上和Java的接口类似但是kotlin的接口可以有抽象方法也可以有已实现的方法
例子:
interface Animal{
val kind
val color
fun doing()
fun eat(){
println("饿了得吃东西")
}
}
class Dog:Animal{
override val kind = "小花狗"
override val color = “黑色的”
overrice fun doing(){
println("正睡觉呢")
}
}
Kotlin的类允许类只能继承一个,但是可以继承多个接口,所以那么可能会有问题就是覆盖冲突
假设我声明的Dog类这个Dog变异了也有人的特性了,让他继承Preson,但是在调用eat()方法就出问题了,super.eat()调用的是谁?这是就可以这么调用:
super.eat()
super.eat()
这样这个变异Dog也能吃狗粮,也能吃食堂,贼厉害O(∩_∩)O哈哈~
其实抽象类和接口在本质上有区别,虽然用起来很像。
以下是区别:
接口主要是对动作的抽象,定义了行为特性的规约。 抽象类是对根源的抽象。当你关注一个事物的本质的时候,用抽象类;当你关注一个操作的时候,用接口。
语法层面上的区别
接口不能保存状态,可以有属性但必须是抽象的。 一个类只能继承一个抽象类,而一个类却可以实现多个接口。
类如果要实现一个接口,它必须要实现接口声明的所有方法。但是,类可以不实现抽象类声明的所有方法,当然,在这种情况下,类也必须得声明成是抽象的。
接口中所有的方法隐含的都是抽象的。而抽象类则可以同时包含抽象和非抽象的方法。
设计层面上的区别
抽象类是对一种事物的抽象,即对类抽象,而接口是对行为的抽象。抽象类是对整个类整体进行抽象,包括属性、行为,但是接口却是对类局部(行为)进行抽象。
继承是 is a
的关系,而 接口实现则是 has a
的关系。如果一个类继承了某个抽象类,则子类必定是抽象类的种类,而接口实现就不需要有这层类型关系。
设计层面不同,抽象类作为很多子类的父类,它是一种模板式设计。而接口是一种行为规范,它是一种辐射式设计。也就是说:
对于抽象类,如果需要添加新的方法,可以直接在抽象类中添加具体的实现,子类可以不进行变更;
实际应用上的差异
在实际使用中,使用抽象类(也就是继承),是一种强耦合的设计,用来描述A is a B
的关系,即如果说A继承于B,那么在代码中将A当做B去使用应该完全没有问题。比如在Android中,各种控件都可以被当做View去处理。
如果在你设计中有两个类型的关系并不是is a
,而是is like a
,那就必须慎重考虑继承。因为一旦我们使用了继承,就要小心处理好子类跟父类的耦合依赖关系。组合优于继承。