- VisualStudio2022插件的安装及使用-编程手把手系列文章
- pprof-在现网场景怎么用
- C#实现的下拉多选框,下拉多选树,多级节点
- 【学习笔记】基础数据结构:猫树
Kotlin 是面向对象编程语言,与 Java 语言类似,都有类、对象、属性、构造函数、成员函数,都有封装、继承、多态三大特性,不同点如下.
在包下面右键,依次点击【New → Kotlin Class/File】,输入类名后,创建 Kotlin 类文件.
如下,创建了一个 Student.kt 文件.
package com.zhyan8.kotlinStudy
class Student {
}
笔者为简化代码,将定义的类与 main 函数放在同一个文件中了.
如下,Student 类是一个自定义的类,里面包含了一个类的基本结构.
fun main() {
var stu1 = Student()
stu1.study()
println("-----------------------------------------")
var stu2 = Student("li si", 23)
}
class Student {
private var name: String = "zhang san" // 属性
get() { // name的getter函数
return field
}
set(value) { // name的setter函数
field = value
}
private var age: Int = 18 // 属性
init { // 初始化代码块, 在构造函数前执行
println("Student init, name=$name, age=$age")
}
constructor() { // 无参构造函数
println("create-1, name=$name, age=$age")
}
constructor(name: String, age: Int) { // 有参构造函数
println("create-2, name=$name, age=$age")
this.name = name
this.age = age
}
fun study() { // 成员函数
println("study...")
}
}
说明:init 代码块可以有多个,按照从前往后的顺序执行;上述构造函数都是次要构造函数,第 3 节中会介绍主构造函数.
运行程序后,打印如下.
Student init, name=zhang san, age=18
create-1, name=zhang san, age=18
study...
-----------------------------------------
Student init, name=zhang san, age=18
create-2, name=li si, age=23
主构造函数是紧接在类名后面的构造函数,次要构造函数是类体内部定义的构造函数,它们的区别如下.
fun main() {
var stu1 = Student()
println("-----------------------------------------")
var stu2 = Student("zhang san")
}
class Student() { // 等价与: class Student constructor()
init { // 初始化代码块, 在构造函数前执行
println("init")
}
constructor(name: String): this() {
println("constructor, name=$name")
}
}
运行程序后,打印如下.
init
-----------------------------------------
init
constructor, name=zhang san
class Student() 等价于 class Student constructor(),如果需要对主构造函数的权限进行控制,可以修改如下.
class Student private constructor() {
...
}
fun main() {
var stu1 = Student("xiao ming", 23)
println("-----------------------------------------")
// stu1.name // 编译报错, name不是成员属性
var stu2 = Student()
}
class Student(name: String, age: Int) {
init {
println("init, name=$name, age=$age")
}
constructor(): this("zhang san", 18) {
println("constructor")
}
}
运行程序后,打印如下.
init, name=xiao ming, age=23
-----------------------------------------
init, name=zhang san, age=18
constructor
fun main() {
var stu1 = Student("xiao ming", 23)
println("stu1.name=${stu1.name}, stu1.age=${stu1.age}")
println("-----------------------------------------")
var stu2 = Student()
println("stu2.name=${stu2.name}, stu2.age=${stu2.age}")
}
class Student(var name: String, var age: Int) {
init {
println("init, name=$name, age=$age")
}
constructor(): this("zhang san", 18) {
println("constructor")
}
}
说明:在主构造函数中,通过给入参添加 var(变量)或 val(常量)修饰,使得参数变为成员属性;在次要构造函数中,不能给入参添加 var 或 val 修饰.
运行程序后,打印如下.
init, name=xiao ming, age=23
stu1.name=xiao ming, stu1.age=23
-----------------------------------------
init, name=zhang san, age=18
constructor
stu2.name=zhang san, stu2.age=18
如果用户想修改入参属性的权限,可以在 var 或 val 前面添加权限修饰符.
class Student(private val name: String, protected var age: Int) {
...
}
封装是指将相关联的属性和函数封装到同一个类中,并且可以控制这些属性和函数的访问权限,它通过隐藏内部细节和提供清晰的接口,提高了代码的安全性、可维护性和可理解性,它是面向对象编程中的重要概念之一.
在 Kotlin 中,有四种访问权限修饰符:private、protected、internal 和 public。这些修饰符控制了代码中类、函数、属性等成员的可见性和访问权限.
继承是指一个类(称为子类或派生类)基于另一个类(称为父类或基类)创建新类,子类继承了父类的属性和函数,并且可以在此基础上进行扩展或修改,它是面向对象编程中的重要概念之一。在 Kotlin 中,继承使用冒号(:)来表示,Any 类是所有类的基类.
类的初始化顺序如下.
fun main() {
var stu = Student("zhang san", 23, 1001)
}
open class People(var name: String) {
init {
println("People init, name=$name") // 1
}
constructor(name: String, age: Int): this(name) {
println("People constructor, name=$name, age=$age") // 2
}
}
class Student : People {
init {
println("Student init, name=$name") // 3 (此处不能访问age和id)
}
constructor(name: String, age: Int, id: Int) : super(name, age) {
println("Student constructor, name=$name, age=$age, id=$id") // 4
}
}
说明:子类必须直接或间接调用一下父类的一个构造函数,否则编译报错.
运行程序后,打印如下.
People init, name=zhang san
People constructor, name=zhang san, age=23
Student init, name=zhang san
Student constructor, name=zhang san, age=23, id=1001
fun main() {
var stu = Student("zhang san", 23, 1001)
}
open class People(var name: String) {
init {
println("People init, name=$name") // 1
}
constructor(name: String, age: Int): this(name) {
println("People constructor, name=$name, age=$age") // 2
}
}
class Student(name: String, var age: Int) : People(name, age) {
init {
println("Student init, name=$name, age=$age") // 3 (此处不能访问id)
}
constructor(name: String, age: Int, id: Int): this(name, age) {
println("Student constructor, name=$name, age=$age, id=$id") // 4
}
}
说明:子类必须直接或间接调用一下父类的一个构造函数,否则编译报错;当子类中有主构造函数时,子类中的次要构造函数.
运行程序后,打印如下.
People init, name=zhang san
People constructor, name=zhang san, age=23
Student init, name=zhang san, age=23
Student constructor, name=zhang san, age=23, id=1001
多态是指同一个函数可以在不同的对象上表现出不同的行为,这种行为通常通过继承和接口来实现。多态使得代码更加灵活和可扩展,是面向对象编程中的重要概念之一.
fun main() {
var peo: People = Student("li si", 25, 1002)
peo.say()
}
open class People(var name: String, var age: Int) {
init {
println("People init, name=$name, age=$age")
}
open fun say() {
println("People say")
}
}
class Student(name: String, age: Int, var id: Int) : People(name, age) {
init {
println("Student init, name=$name, age=$age, id=$id")
}
override fun say() {
println("Student say")
}
}
运行程序后,打印如下.
People init, name=li si, age=25
Student init, name=li si, age=25, id=1002
Student say
fun main() {
var peo : People = Student()
peo.doSomething()
}
open class People {
open var name: String = "zhang san"
fun doSomething() {
println("doSomething, name=$name")
}
}
class Student : People() {
override var name: String = "li si"
}
运行程序后,打印如下.
doSomething, name=li si
fun main() {
var peo: People = Student()
// peo.study() // 编译报错
if (peo is Student) {
peo.study() // 智能转换为Student
}
}
open class People {
}
class Student : People() {
fun study() {
println("study...")
}
}
说明:Java 没有智能转换特性,需要进行强制类型转换.
使用 abstract 修饰的类称为抽象类,抽象类中可以有抽象属性和函数,这些属性和函数被添加了 abstract 修饰符,父类不能实现,子类必须重写实现(子类如果也是抽象类除外)。抽象类不能被实例化,只能实例化其具化子类,抽象类中允许有具化的属性和函数.
fun main() {
// var peo = People() // 编译报错, 抽象类不能被实例化
var stu = Student()
stu.say()
}
abstract class People {
abstract var name: String
abstract fun say()
}
class Student : People() {
override var name: String = "xiao min"
override fun say() {
println("$name: Hello")
}
}
说明:Java 中只有抽象函数,没有抽象属性.
运行程序后,打印如下.
xiao min: Hello
接口与抽象类有些类似,接口里只有抽象属性和函数(函数允许有默认实现,属性不能),Kotlin 中允许一个类实现多个接口,但最多只能继承一个类.
fun main() {
var c = C("xxx", "yyy")
c.aFun()
c.bFun()
}
interface A {
var x: String
fun aFun()
}
interface B {
var y: String
fun bFun()
}
class C(override var x: String, override var y: String) : A, B {
override fun aFun() {
println("aFun, x=$x")
}
override fun bFun() {
println("bFun, y=$y")
}
}
运行程序后,打印如下.
aFun, x=xxx
bFun, y=yyy
1)枚举类 。
enum class Color(val tag: String) {
RED("red") {
override fun test() {
println("test, $tag")
}
},
GREEN("green") {
override fun test() {
println("test, $tag")
}
},
BLUE("blue") {
override fun test() {
println("test, $tag")
}
};
fun printColor(): Unit {
println("color=$tag")
}
abstract fun test()
}
2)enumValueOf、enumValues 。
fun main() {
var color: Color = enumValueOf<Color>("RED")
var colors: Array<Color> = enumValues<Color>()
println(colors.joinToString()) // RED, GREEN, BLUE
}
3)name、ordinal、entries、values 。
fun main() {
println(Color.GREEN.name) // GREEN
println(Color.RED.ordinal) // 0
var entries: EnumEntries<Color> = Color.entries
println(entries) // [RED, GREEN, BLUE]
var colors: Array<Color> = Color.values()
println(colors.joinToString()) // RED, GREEN, BLUE
}
4)自定义属性和函数 。
fun main() {
Color.RED.printColor() // color=red
Color.GREEN.test() // test, green
println(Color.BLUE.tag) // blue
}
在 class 前面添加 data 关键字表示为一个数据类,编译器会根据主构造函数中声明的所有属性自动为其生成以下函数.
fun main() {
val stu1 = Student("Zhang", 20)
val stu2 = Student("Zhang", 20)
// hashCode、equals
println(stu1 == stu2) // true
// toString
println(stu1) // Student(name=Zhang, age=20)
// componentN
var (name, age) = stu1
println("($name, $age)") // (Zhang, 20)
// copy
var stu3 = stu1.copy()
}
data class Student(var name: String, var age: Int)
为了确保生成代码的一致性和有效性,数据类必须满足以下要求.
数据类中成员函数的生成遵循以下规则.
声明:本文转自【Kotlin】类和对象.
最后此篇关于【Kotlin】类和对象的文章就讲到这里了,如果你想了解更多关于【Kotlin】类和对象的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我的一位教授给了我们一些考试练习题,其中一个问题类似于下面(伪代码): a.setColor(blue); b.setColor(red); a = b; b.setColor(purple); b
我似乎经常使用这个测试 if( object && object !== "null" && object !== "undefined" ){ doSomething(); } 在对象上,我
C# Object/object 是值类型还是引用类型? 我检查过它们可以保留引用,但是这个引用不能用于更改对象。 using System; class MyClass { public s
我在通过 AJAX 发送 json 时遇到问题。 var data = [{"name": "Will", "surname": "Smith", "age": "40"},{"name": "Wil
当我尝试访问我的 View 中的对象 {{result}} 时(我从 Express js 服务器发送该对象),它只显示 [object][object]有谁知道如何获取 JSON 格式的值吗? 这是
我有不同类型的数据(可能是字符串、整数......)。这是一个简单的例子: public static void main(String[] args) { before("one"); }
嗨,我是 json 和 javascript 的新手。 我在这个网站找到了使用json数据作为表格的方法。 我很好奇为什么当我尝试使用 json 数据作为表时,我得到 [Object,Object]
已关闭。此问题需要 debugging details 。目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and the
我听别人说 null == object 比 object == null check 例如: void m1(Object obj ) { if(null == obj) // Is thi
Match 对象 提供了对正则表达式匹配的只读属性的访问。 说明 Match 对象只能通过 RegExp 对象的 Execute 方法来创建,该方法实际上返回了 Match 对象的集合。所有的
Class 对象 使用 Class 语句创建的对象。提供了对类的各种事件的访问。 说明 不允许显式地将一个变量声明为 Class 类型。在 VBScript 的上下文中,“类对象”一词指的是用
Folder 对象 提供对文件夹所有属性的访问。 说明 以下代码举例说明如何获得 Folder 对象并查看它的属性: Function ShowDateCreated(f
File 对象 提供对文件的所有属性的访问。 说明 以下代码举例说明如何获得一个 File 对象并查看它的属性: Function ShowDateCreated(fil
Drive 对象 提供对磁盘驱动器或网络共享的属性的访问。 说明 以下代码举例说明如何使用 Drive 对象访问驱动器的属性: Function ShowFreeSpac
FileSystemObject 对象 提供对计算机文件系统的访问。 说明 以下代码举例说明如何使用 FileSystemObject 对象返回一个 TextStream 对象,此对象可以被读
我是 javascript OOP 的新手,我认为这是一个相对基本的问题,但我无法通过搜索网络找到任何帮助。我是否遗漏了什么,或者我只是以错误的方式解决了这个问题? 这是我的示例代码: functio
我可以很容易地创造出很多不同的对象。例如像这样: var myObject = { myFunction: function () { return ""; } };
function Person(fname, lname) { this.fname = fname, this.lname = lname, this.getName = function()
任何人都可以向我解释为什么下面的代码给出 (object, Object) 吗? (console.log(dope) 给出了它应该的内容,但在 JSON.stringify 和 JSON.parse
我正在尝试完成散点图 exercise来自免费代码营。然而,我现在只自己学习了 d3 几个小时,在遵循 lynda.com 的教程后,我一直在尝试确定如何在工具提示中显示特定数据。 This code
我是一名优秀的程序员,十分优秀!