Kotlin学习快速入门(3)——类 继承 接口

简介: Kotlin学习快速入门(3)——类 继承 接口作者:@stars-one本文为作者原创,转载请注明出处:https://www.cnblogs.com/kexing/p/11262112.html类参考链接类定义格式使用class关键字定义,格式如下:复制class T{//属性//构...

Kotlin学习快速入门(3)——类 继承 接口
作者:@stars-one
本文为作者原创,转载请注明出处:https://www.cnblogs.com/kexing/p/11262112.html


参考链接

类定义格式
使用class关键字定义,格式如下:

复制
class T{

//属性
//构造函数
//函数
//内部类

}
Java Bean类
java bean类
复制
//java bean类
public class Student {

private String name;
private int age;

public Student() {
}

public Student(String name) {
    this.name = name;
}

public Student(String name, int age) {
    this.name = name;
    this.age = age;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public int getAge() {
    return age;
}

public void setAge(int age) {
    this.age = age;
}

}
java bean类(kotlin实现)
复制
//kotlin写法,get和set方法默认实现
class Student {

/注意,这里的var代表着变量的数值之后可以被修改,也可以使用只读val
//?是可为空的写法,后面会提到
//这里其实包含了主构造方法,不过因为主构造方法为空,所以省略了
var name: String? = null
var age: Int = 0

//这几个constructor是次级构造方法
constructor() {}

constructor(name: String) {
    this.name = name
}

constructor(name: String, age: Int) {
    this.name = name
    this.age = age
}

}

//下面是没有省略主构造方法的
//注意,因为把默认的主构造方法写了出来,所以,不允许出现无参数的次构造方法
class Student public constructor() {

//注意,这里的var代表着变量的数值之后可以被修改,也可以使用只读val
//?是可为空的写法,后面会提到
//这里其实包含了主构造方法,不过因为主构造方法为空,所以省略了
var name: String? = null
var age: Int = 0

//这几个constructor是次级构造方法
constructor(name: String) : this() {
    this.name = name
}

constructor(name: String, age: Int)  : this(){
    this.name = name
    this.age = age
}

}
主函数调用
复制
//主函数调用
fun main(args: Array){

//声明类不需要new关键字
val student = Student("star",12)
//,使用对象.属性名调用,而不是使用get或set
println(student.age)//获得属性
student.name = "stars"//修改属性

}
主构造方法(kotlin)
kotlin类中可以有主构造方法和次构造方法,次构造方法也就是上面那段使用kotlin实现的Java Bean类(上面的主构造方法其实是省略了的)

复制
/*下面三种方法都是声明了一个Student类
*Student包含了一个构造方法(两个参数),还有两个成员变量以及成员变量对应的get和set方法
*/

//原始方式,使用主构造方法
class Student public constructor(name: String,age: Int) {

//注意,这里的var代表着变量的数值之后可以被修改,也可以使用只读val
var name = name
var age = age

}

//简洁写法,如果主构造方法只有默认的修饰符(public,默认的修饰符可省略),可以把constructor省略
class Student(name: String,age: Int) {

var name = name
var age = age

}

//更简洁写法
class Student(var name: String,var age: Int) {
}

//使用Student类
fun main(args: Array) {

//声明类不需要new关键字
val student = Student("star",12)
println(student.name)
println(student.age)
student.age = 19 //修改内容
println(student.age)

}
init(初始化块)
如果我们想要在主构造方法进行初始化操作,需要在init代码块里面写我们的代码,如

复制
//更简洁写法
class Student(var name: String,var age: Int) {

init{
    println("这里是初始化操作")
}

}
注意,初始化块是主构造方法的一部分

初始化操作会在次构造方法之前执行,即使没有写主构造方法,如:

复制
class Student{

var name: String? = null
var age: Int = 0

init{
    println("这里是初始化操作")
}

constructor(name: String, age: Int) {
    this.name = name
    this.age = age
}

}
主/次构造方法联合使用
类定义了主构造器,次构造器必须直接或间接调用主构造器;

复制
class Student() {

var name: String? = null
var age: Int = 0

//这几个constructor是次级构造方法,,这里的this()就是当前的主构造方法
constructor(name: String) : this() {
    this.name = name
}

constructor(name: String, age: Int)  : this(){
    this.name = name
    this.age = age
}

}
复制
class Student public constructor() {

var name: String? = null
var age: Int = 0

//这几个constructor是次级构造方法,,这里的this()就是当前的主构造方法
//这里用专业术语说,是次级构造方法需要委托给主构造方法
constructor(name: String) : this() {
    this.name = name
}

constructor(name: String, age: Int)  : this(){
    this.name = name
    this.age = age
}

}
伴生方法(静态方法)
复制
class Student{

...
companion object {
    @JvmStatic
    //下面定义一些方法
    fun sayHello() {
        println("hello")
    }
}

}
get/set方法修改
看完上面,我们都知道kotlin默认帮我们实现了get和set方法,val修饰的变量是只读的,所以该变量没有setter方法

格式:

复制
var [: ] [= ]

[<getter>]
[<setter>]

//表达式写法
get() = ...
//花括号写法
get(){

...
return xx

}
复制
class Student() {

var name: String = ""
var age: Int = 0
//这里使用val
val isNameEmpty: Boolean
    get() = name.length==0

//使用var就得赋值
//val isNameEmpty: Boolean
//    get() = name.length==0

constructor(name: String) : this() {
    this.name = name
}

constructor(name: String, age: Int)  : this(){
    this.name = name
    this.age = age
}

}
如果要在get和set引用当前的字段(属性值),得使用filed关键字代替内容

复制
class Student() {

var name: String = ""
    //如果当前的name为"",则返回小红作为姓名
    //这里的filed就是name,类型也与name一样
    get() {
        return if(field.length==0) "小红" else field
    }
var age: Int = 0

constructor(name: String) : this() {
    this.name = name
}

constructor(name: String, age: Int)  : this(){
    this.name = name
    this.age = age
}

}
setter方法与之前的getter方法一样,里面也是使用field代替当前的数值,只不过setter有一个参数,默认为value,可以修改名字

复制
set(value){

filed = vaule

}
嵌套类和内部类
嵌套类和内部类的区别是,嵌套类无法引用外层类的属性和方法,而内部类可以

复制
//Nested为嵌套类
class Outer {

private val bar: Int = 1
class Nested {
    //这里因为是嵌套类,无法引用Outer中的bar
    fun foo() = 2
}

}

val demo = Outer.Nested().foo() // == 2
内部类,使用inner关键字

复制
class Outer {

private val bar: Int = 1
inner class Inner {
    //这里可以引用bar
    fun foo() = bar
}

}

val demo = Outer().Inner().foo() // == 1
继承和接口
继承
kotlin所有的类都是继承于Any,注意,Any 并不是 java.lang.Object

kotlin中的类默认是不可继承的,需要有open关键字修饰类,需要在子类复写的方法,也得在父类用open修饰该方法

复制
open class Person{

var name: String = ""
var age: Int =0

constructor(){}
constructor(name: String, age: Int){
    this.name = name
    this.age = age
}

open fun hello() {
    println("hello this is person")
}

}

class Student: Person {

constructor() : super(){}
constructor(name: String,age: Int) :super(name,age){}

override fun hello() {
    println("hello this is student")
}

}
接口
接口的实现也是使用:,声明接口也是interface关键字,注意,kotlin中的接口方法可以实现

复制
interface Print {

fun print()
fun say(){
    println("sayhello")
}

}
Student类继承Person并实现Print接口:

复制
class Student: Person,Print {

override fun print() {
    //复写接口里的方法
}

constructor(name: String,age: Int) :super(name,age){}

override fun hello() {

}

}
数据类
介绍
kotlin提供了一个数据类,专门类存放数据,使用关键字data修饰类

官方的关于数据类的规范:

主构造函数需要至少有一个参数;
主构造函数的所有参数需要标记为 val 或 var;
数据类不能是抽象、开放、密封或者内部的;
(在1.1之前)数据类只能实现接口。
数据类主要有下面两种特点:

自动解析
直接复制
数据类定义
复制
data class Person(var name: String,var age: Int){
}
自动解析
自动解析有顺序,根据类中属性的属性

复制
val person = Person("star",19)
//val括号里可以根据需要选择不同参数,注意顺序,不能跳过一个不需要的属性
val(name,age) = person
println("$name, $age years of age") // 输出 "star, 19 years of age"
复制
复制
val person = Person("star",19)
val person1 = person.copy()
//复制并修改部分属性
val person2 = person.copy(age =23)
总结
个人觉得,如果某个类只有一个构造方法,可以定义类只含有一个主构造方法即可,使用那个最简洁的方式。

如果需要有不同参数的构造方法(或者是Java Bean),则使用次级构造方法

如果是用来当做数据类,则使用数据类定义

相关文章
|
4天前
|
Java Kotlin
Kotlin教程笔记(12) - 面向对象之继承与实现
Kotlin教程笔记(12) - 面向对象之继承与实现
|
9天前
|
数据安全/隐私保护 Kotlin
Kotlin - 类成员
Kotlin - 类成员
45 6
|
9天前
|
Java 物联网 Kotlin
Kotlin - 面向对象之抽象类与接口
Kotlin - 面向对象之抽象类与接口
|
7天前
|
Java Kotlin
Kotlin - 类及成员的可见性
Kotlin - 类及成员的可见性
|
10天前
|
Java Kotlin
Kotlin - 类及成员的可见性
Kotlin - 类及成员的可见性
26 5
|
9天前
|
数据安全/隐私保护 Kotlin
Kotlin - 类成员
Kotlin - 类成员
22 2
|
10天前
|
Java Kotlin
Kotlin - 面向对象之继承与实现
Kotlin - 面向对象之继承与实现
23 4
|
12天前
|
Kotlin
Kotlin教程笔记(20) - 枚举与密封类
Kotlin教程笔记(20) - 枚举与密封类
26 3
|
7天前
|
存储 前端开发 Java
Kotlin - 数据类
Kotlin - 数据类
16 0
|
12天前
|
存储 前端开发 Java
Kotlin教程笔记(18) - 数据类
Kotlin教程笔记(18) - 数据类
16 0
下一篇
无影云桌面