一、变量的声明
在Kotlin中变量的声明以关键字开始,然后是变量名称,最后可以加上类型(不加也可以,不加的话需要给变量赋值)。
声明变量的关键字:
① val(来自value)—— 不可变引用。使用val声明的变量不能在初始化之后再次赋值,对应于Java的final 变量。
② var(来自 variable)—— 可变引用。这种变量的值可以改变,对应的是普通(非final)的Java变量。
默认情况下,应尽可能使用 val 关键字来声明所有的 Kotlin 变量,仅在必要的时候换成var。
可以在变量名称前面加上 字符$ 来引用该变量:
//kotlin
fun main(args:Array<String>){
val name = if(args.size>0) args[0] else "kotlin"
println("Hello, $name!") //等价于 ("Hello," + name + "!")
}
注意:
1)如果要在字符串中使用$字符,要对它转义,println(“\$x”),会打印出$x,并不会把x解释成变量的引用
2)引用更复杂的表达式时,只需要把表达式用花括号括起来:
fun main(args:Array<String>){
if(args.size>0){
println("Hello, ${args[0]}")
}
}
二、类中的属性
(1)基础概念
在 Java 中,字段和其访问器的组合,常常被叫做属性。
在Kotlin中,声明为 val 的属性是只读的,而 var 的是可变的,当声明属性的时候,就声明了对应的访问器:
class Person(name:String, isMarried:Boolean){
val p_name : String? = name //只读,生成一个字段和一个简单的getter(getName())
var p_isMarried : Boolean? = isMarried //可写,生成一个字段、一个getter(isMarried) 和 一个setter(setMarried)
//getter和setter的命名规则有一个例外:
//如果属性的名称以 is 开头,
//getter名称中不会增加任何前缀
//setter名称中的is会被替换成set
}
在 Java 代码中使用 Person:
//java
Person person = new Person("Bob", true);
System.out.println(person.getName()); //-->Bob
System.out.println(person.isMarried()); //-->true
在 Kotlin 代码中使用 Person:
//Kotlin
val person = Person("Bob", true)
println(person.name)
person.isMarried = false
println(person.isMarried)
注意,Kotlin中没有getter和setter方法,直接调用该属性就可以。
(2)自定义属性访问器
//Kotlin
class Rectangle(val height:Int, val width:Int){
val isSquare : Boolean //属性 isSquare 的值是每次访问属性的时候计算出来的
get(){
return height == width
}
}
上述代码也可以写为:
//Kotlin
class Rectangle(val height:Int, val width:Int){
val isSquare : Boolean //属性 isSquare 的值是每次访问属性的时候计算出来的
get() = height == width
}
val rectangle = Rectangle(41, 43)
println(rectangle.isSquare)
如果要在 Java 中访问这个属性,可以声明一个 isSquare() 方法,并进行调用。
声明一个无参函数 和 声明 带自定义 getter 的属性 在实现和性能上都没有差别,唯一的差异是可读性。
(3)标识符 field
class User(val name:String){
var address:String = "unSpecified"
set(value:String){
println("""Address was changed for $name: $field -> $value""".trimIndent())
field = value //field用来访问支持字段的值,这里指的是 address
}
}
fun main(args:Array<String>){
val user = User("Alice")
user.address = "123456"
}
在属性所对应的 setter 中,使用了特殊的 标识符field 来访问支持字段的值
支持字段:如果显式地引用或者使用默认的访问器来实现属性,编译器会为属性生成支持字段;如果你提供了一个自定义的访问器实现 (val,访问器是getter;var,访问器是getter和setter)并且 没有使用field,支持字段将不会呈现出来。
(4)修改访问器的可见性
访问器的可见性默认与属性的可见性相同,如果修改访问器的可见性的话,可以在 get 和 set 关键字前放置可见性修饰符的方式来修改。
class LengthCounter{
var counter:Int = 0
private set //修改属性的可见性,使得不能在类外部修改此属性 但还是可以访问的
fun addWord(word:String){
counter += word.length
}
}
fun main(args:Array<String>){
val lc = LengthCounter()
lc.addWord("Hello")
println(lc.counter) //5
}
三、接口中的属性
Java 8 以前,接口中可包含:①常量;②抽象方法
Java 8 中,接口中可包含:①常量; ②抽象方法; ③默认方法; ④静态方法
Java 9 中,接口中可包含:①常量;②抽象方法; ③默认方法; ④静态方法;⑤私有方法
Java 在接口中的变量都是 public static final (即静态常量)的,在声明时需要赋初值,写法:
//Java
interface User{
public static final int age = 2;
}
或者
//Java
interface User{
int age = 2; //省略掉 一些修饰符
}
在Kotlin中,接口的属性只能是抽象的,不允许初始化值:
interface User{
var name:String //属性可被 var 修饰,也可被 val 修饰
val gender:Boolean //省略 abstract open 修饰符
}
class Men:User{
//覆盖属性 , 变量只能使用变量覆盖
override var name = "zhangsan"
//覆盖属性 , 可以使用变量覆盖常量 , 反过来不行
override var gender = true
}
但是,可以给常量添加访问器:
interface User{
val name:String //抽象属性 常量 , 常量可以提供一个访问器,在子类中可以不重写
get() = "bob"
var gender:Boolean //抽象属性 变量 , 变量只能声明成抽象属性 , 不能添加访问器
}
class Men() :User{
override var gender = true
}
fun main(arg:Array<String>){
val men = Men()
println("name::${men.name}, gender::${men.gender}")
}
————————————————
版权声明:本文为CSDN博主「浅唱整个春天」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_32677531/article/details/126055850