Java 是一种面向对象编程语言,它基于 Smalltalk 语言,作为 OOP 语言,它具有以下5个基本特性:
class AnEmptyClass
fun main(args : Array<String>} {
val anEmptyClass = AnEmptyClass (){
println(anEmptyClass)
println(anEmptyClass is AnEmptyClass)
println(anEmptyClass : :class)
//输出如下 :
com.easy.kotlin.AnEmptyClass@2626b418
true
class com.easy.kotlin.AnEmptyClass (Kotlin reflection is not available}
在 Kotlin 中,我们可以在声明类的时候同时声明构造函数,语法格式是在类的后面使用括号包含构造函数的参数列表
//声明类和构造函数
class Person (var name: String, var age: Int, var sex: String){
//override 关键字,重写 toString()
override fun toString(): String {
return "Person(name=’$name’, age=$age, sex=’$sex’)"
}
}
//测试
val person = Person(”Jack", 29,”M”)
println(”person =${
person)”)
//输出
person= Person(name=’ Jack ’, age=29 , sex=’M’)
另外,也可以先声明属性,等构造实例对象的时候再去初始化属性值,那么 Person 类可以进行如下声明 :
class Person1 {
lateinit var name: String //lateinit 关键字表示该属性延迟初始化
var age: Int = 0 //lateinit 关键字不能修饰 primitive 类型
lateinit var sex: String
override fun toString(): String {
return "Personl(name= '$name', age=$age , sex='$sex' )"
}
}
//测试
val person1 = Person1()
person1.name = "Jack"
person1.age = 26
person1.sex = "M"
println("person1= $person1")
//输出
person1 = Personl(name = 'Jack', age =26, sex = 'M')
如果我们想声明一个具有多种构造方式的类,可以使用 constructor关键字声明构造函数
class Person2() {
//无参的主构造函数
lateinit var name: String
var age: Int = 0
lateinit var sex: String
//次级构造函数,this 关键字指向当前类对象实例
constructor(name: String) : this() {
this.name = name
}
//次级构造函数
constructor(name: String, age: Int) : this(name) {
this.name = name
this.age = age
}
//次级构造函数
constructor(name: String, age: Int, sex: String) : this(name, age) {
this.name = name
this.age = age
this.sex = sex
}
override fun toString(): String {
return "Personl(name= '$name', age=$age , sex='$sex' )"
}
}
实际上, 我们在 编程实践中用到最多的构造函数还是这个 :
class Person (var name: String , var age : Int , var sex : String)
当需要通过比较复杂的逻辑来构建一个对象的时候,可采用构建者( Builder )模式来实现。
抽象类表示“ is-a”的关系,而接口所代表的是“ has-a”的关系。例如,设计一个图形编辑软件,问题领域中存在着长方形 (Rectangle)、圆形( Circle)、 三角形( Triangle)等一些具体概念,它们是具象。但是它们又都属于形状(Shape)这个抽象的概念。
抽象是相对于具象而言的。
因为抽象的概念在问题领域中没有对应的具体概念,所以抽象类是不能够实例化的。
abstract class Shape //声明抽象父类 Shape
class Rectangle : Shape() //继承类的语法是使用冒号“:” ,父类需要在这里使用构造函数进行初始化
class Circle : Shape() //Circle 继承Shape类
class Triangle : Shape() //Triangle 继承Shape类
当子类继承了某个类之后,便可以使用父类中的成员变量,但并不是完全继承父类的所有成员变量。具体的原则如下 :
接口是一种比抽象类更加抽象的“类“。接口本身代表的是一种”类型“的概念。但在语法层面,接口本身不是类,不能实例化接口,只能实例化它的实现类 。
Kotlin与 Java一样, 不支持同时继承多个父类,也就是说继承 只能存在一个父类(单继承)。
和 Java类似, Kotlin使用 interface作为接口的关键词:
interface A {
val name: String
val owner: String
fun save(project: A)
fun print() {
println("I am project")
}
}
interface B {
val name: String
val owner: String
fun save(project: B)
fun print() {
println("I am Milestone")
}
}
class ProjectMilestoneServiceImpl(override val name: String, override val owner: String) :
A, B {
override fun print() {
//super.print()
super<B>.print()
}
override fun save(a: A) {
TODO("Not yet implemented")
}
override fun save(b: B) {
TODO("Not yet implemented")
}
}
在重写 print()函数时,因为我们实现的 ProjectService、MilestoneService都有一个 print() 函数,当直接使用 super.print() 函数时,编译器无法知道我们想要调用 的是哪个 print 函数,这种现象叫做覆盖冲突。这个时候 ,我们可以 使用下面的语法来调用 :
super<A>.print()
super<B>.print()
Kotlin 中没有静态属性和方法,但是可以使用关键宇 object 声明一个 object单例对象
object User {
//声明对象类型User
val username: String = "admin"
val password: String = "admin"
fun hello() {
println(” Hello, object !”)
}
}
fun main(args : Array<String>) {
println(User .username)
println(" Hello, object !")
User.hello() //与Java静态类的调用形式一样
}
Kotlin 中还提供了伴生对象, 用 companion object 关键字声明:
class DataProcessor {
companion object A {
fun process() {
println("I am processing data....")
}
}
}
fun main (args : Array<String>) {
DataProcessor.process()
}
一个类只能有 一个伴生对象 。
数据类就是只存储数据,不包含操作行为的类。 Kotlin 中的数据类可以为我们节省大量的样板代码
使用关键字为 data class 创建一个只包含数据的类 :
data class LoginUser(val username : String, val password : String)
自动创建以下 3 个函数
数据类有如下限制 :
data class LoginUser(val username: String, val password: String)
fun main(args: Array<String>) {
val loginUser = LoginUser("admin", "admin")
val (username, password) = loginUser
println("username=$username, password=$password")
}
Kotiin 标准库提供了 Pair和 Triple数据类, 分别表示二元组和三元组对象。
data class Pair<out A, out B>(val first: A, val second: B) : Serializable {
override fun toString(): String = "($first,$second)"
}
使用 Pair 对象来初始化一个 Map
Katlin中使用 enumclass关键字来声明一个枚举类, 枚举类有两个内置的属性 ,分别表示的是枚举对象的值与下标位置
enum class Direction {
NORTH,SOUTH,WEST,EAST
}