1、类
类表示一种具体对象的抽象化,比如说人表示一个类,那么我自己就是具体对象;在类中会有属性描述类的对象状态,函数描述类的对象函数;Kotlin 和 Java 一样都是使用 class 关键字修饰对应类的名称;下面用 kotlin 代码定义一个类:
ps:代码是用 AndroidStudio 写的
/**
* 定义一个类,名叫 Person
*/
class Person {
/**
* 定义一个 String 类型的属性 name
*/
var name: String? = null
/**
* 定义一个 Int 类型的属性 age
*/
var age: Int = 0
constructor(name: String,age: Int) {
this.name = name
this.age = age
}
/**
* 定义一个函数,名叫 eat
*/
fun eat() {
var s:String = "我叫" + name + ",今年" + age + "岁,现在正在吃饭"
println(s)
}
}
2、对象
对象就是类的具体化或者说是类的实例化,创造一个对象不需要 new 关键字,只需要 “类名()” 就可以成功的实例化一个类。
3、 静态属性和动态行为
在一个类中声明的基本的数据类型或者复杂的数据类型就叫做静态属性,这里的静态属性并非是说静态类型的数据类型,只是我们约定俗成把属性说成是静态的,不要搞混淆了;在上面定义的 Person 类中,name 和 age 就是静态属性,要用的时候只需对象调用;在一个类中定义的函数就是定义动态行为,就拿 Person 类来说,eat() 函数就是动态行为,要用的时候也需对象调用。
4、 封装
封装其实就是隐藏内部的实现细节,就拿一个类来说,把它的某一个函数用 private 来定义,那么就是对这个类进行封装,在外部不能通过对象访问到,只能通过对象内部访问到,也就是说通过对象函数访问到对象自己的 private 定义的函数;下面举个例子:
(1)定义一个打印机类。
class Printer {
/**
* 这里用 printSpeed 函数对打印速度进行封装,用 private 声明;
* 不能随便由外部进行随意更改
*/
private fun printSpeed(num: Int) {
println("1分钟打印" + num + "张纸")
}
fun printPaper() {
/**
* 这里对象函数才能调用对象本身的 private 函数,
* 外部不能调用对象的 private 方法
*/
printSpeed(10)
}
}
(2)外部调用打印机类对象的 printPaper 方法,不能直接调用 printSpeed 方法。
var printer: Printer = Printer()
printer.printPaper()
5、 继承
一个对象可以使用另一个对象的非私有属性和非私有方法就叫继承,就打个比方说,学生也可以继承人类 Person 的 name、age 属性和 eat 方法,一个类继承另外一个类用 : 表示,在被继承的类定义时要加上 open 关键字,因为在 kotlin 语言中类是默认 final 类型的(如果不是抽象类或者接口);下面举个例子:
(1)定义一个 Student 类并继承 Person 类,在 Person 类之前加个 open 关键字。
class Student(name: String,age: Int): Person(name,age) {
}
(2)对继承父类的 eat 方法直接调用。
var student: Student = Student("小二",21)
student.eat()
6、 重写
当一个类继承另一个类的时候,子类可以重写父类的非私有方法;重写可以理解成当父类有自己梦想的时候,子类继承父类梦想的同时也可以有自己的小梦想;子类重写函数时要加 override 关键字,当子类对象调用父类和子类相同函数名的函数时,调用的是子类对象重写的函数,而不再是父类对象的函数;在被继承的类的函数之前加上 open 关键字,因为在 kotlin 语言中函数是默认 final 类型不可重写的(如果不是抽象函数);下面举个例子:
(1)在 Person 类的基础上添加一个 dream 函数。
open fun dream() {
var s:String = "我叫" + name + ",今年" + age + "岁,我都梦想是让生活变得美好。"
println(s)
}
(2)在 Student 类的基础上重写 dream 函数。
override fun dream() {
var s:String = "我叫" + name + ",今年" + age + "岁,我都梦想是去做生意。"
println(s)
}
(3)对 dream 函数进行调用
var student: Student = Student("小二",21)
/**
* 这里调用的是 Student 本身的,而不是 Person 的
*/
student.dream()
7、 抽象类
含有 abstract 关键字的类就叫做抽象类,抽象类可以有抽象函数也可以一个都没有;如果有抽象函数的话,继承抽象类的类必须实现抽象类所有的抽象函数;抽象类是不用加 open 关键字的,因为它默认是可继承的;下面举个例子:
(1)新建一个抽象类 Father。
abstract class Father {
abstract fun study()
}
(2)新建一个 Son 类并继承 Father 类和实现 study 函数。
class Son: Father() {
override fun study() {
var s: String = "我是 Son ,我要学习"
println(s)
}
}
(3)调用 study 函数。
var son: Son = Son()
son.study()
8、 接口
接口是指实体把自己提供给外界的一种抽象化物,用以由内部操作分离出外部沟通方法;在 kotlin 语言中,接口是特殊的抽象类,它可以声明有函数,也可以没有,如果声明有函数,那么它所有的函数都是抽象函数;定义接口用 interface 关键字,而不再是 class 关键字,也不用添加 open 关键字,因为它是默认可继承的供外部使用;接口中声明的函数不用写关键字 open 和 abstract,因为它是抽象函数,给子类去实现的;子类实现接口时,接口后面不能加括号;下面举个例子:
(1)定义一个接口 MyInterface。
interface MyInterface {
fun callback()
}
(2)定义一个实现类 MyInterfaceImplement。
class MyInterfaceImplement: MyInterface {
override fun callback() {
var s: String = "我是 MyInterfaceImplement 类对象,我实现了 MyInterface 接口的 callback 函数"
println(s)
}
}
(3)调用接口方法。
var myInterfaceImplement: MyInterfaceImplement = MyInterfaceImplement()
myInterfaceImplement.callback()
9、 多态
同种功能,不同表现形式就叫多态;什么意思呢?就比如说一个抽象类有一个抽象函数,多个子类都继承这个抽象类,那么这个抽象类的抽象函数就是同种功能,多个子类用不同代码去实现了抽象类的函数就是不同表现形式;下面举个例子:
(1)在 MyInterface 的基础上,新建一个 MyInterfaceImplement2 类并实现 MyInterface 接口。
class MyInterfaceImplement2: MyInterface {
override fun callback() {
var s: String = "我是 MyInterfaceImplement2 类对象,我实现了 MyInterface 接口的 callback 函数"
println(s)
}
}
(2)实例化多个 MyInterface 接口,并调用它们函数。
/**
* 向上转型
*/
var myInterface: MyInterface = MyInterfaceImplement()
var myInterface2: MyInterface = MyInterfaceImplement2()
var list: List = listOf(myInterface,myInterface2)
for (myInterface: MyInterface in list) {
/**
* 这里虽然是同一接口函数,但是却是 MyInterfaceImplement 和 MyInterfaceImplement2 函数具体的代码
*/
myInterface.callback()
}
10、 委托和代理
委托就是把事情委托给他人,代理是用他人的名义,在许可的情况下对被代理人直接发生法律作用的行为;比如说,歌手去签约,但是他不直接去签约,还是叫助理去签约,这就是典型的委托和代理模式;下面举个例子:
(1)定义一个接口 Company。
interface Company {
fun sign()
}
(2)定义一个歌手助理类 SingerAssistant,并实现 Company 接口。
class SingerAssistant: Company {
override fun sign() {
var s: String = "我是歌手的助理,我代理歌手签约"
println(s)
}
}
(3)定义一个歌手类 Singer ,实现 Company 接口但不实现函数而是用 SingerAssistant 代理去实现函数。
class Singer: Company by SingerAssistant() {
}
(4)调用歌手签约函数。
var company: Company = Singer()
/**
* 这里原本是 Singer 去实现函数,但是它使用了委托,
* 所以由 SingerAssistant 代理去实现函数
*/
company.sign()
11、 单例模式
在一个进程中,有且只有一个类对象就叫做单例模式;在 kotlin 语言中,创建单例模式,只需要在某个类中添加 object 关键字并把 calss 关键字去掉,就可以让 JVM 做好实例化了,并且只会出现一个实例;下面举个例子:
(1)定义一个单例模式类 Singleton。
object Singleton {
fun action() {
var s:String = "我是单例类对象,不允许实例化1个以上对象"
println(s)
}
}
(2)对该单例模式的类对象方法进行调用。
/**
* 这里因为定义了是单例模式的类,
* 所以调用的时候只需要类名调用就可以了
*/
Singleton.action()
/**
* 这里会报错,因为是单例模式,不能再实例化一个类对象了
*/
var singleton: Singleton = Singleton()
12、 印章类
印章类又称为密封类,用来表示受限的类继承结构:当一个值为有限几种的类型, 而不能有任何其他类型;也可以理解为受限的子类,它是枚举型的扩展,不同的是枚举型是有限的数据个数,而印章类是有限的子类类型;使用sealed关键字修饰类,印章类可以有子类,但是所有的子类都必须要内嵌在印章类中;下面举个例子:
(1)定义一个印章类 Snake。
sealed class Snake {
class WaterSnake(): Snake()
class GrassSnake(): Snake()
fun sayName(name: String) {
println(name)
}
}
(2)调用印章类所有子类的函数。
var snake: Snake = Snake.GrassSnake()
var snake2: Snake = Snake.WaterSnake()
var list:List = listOf(snake,snake2)
for (snakes: Snake in list) {
snakes.sayName()
}
本篇文章写到这里就结束了,由于技术水平有限,文章中难免会有错误,欢迎大家批评指正,另外附上demo地址:https://github.com/Yubao1/KotlinClass.git
关注微信公众号,阅读更多文章