构造器
kotlin允许定义一个柱构造器和若干个第二构造器,主构造器是类头的一部分,构造器的参数是可选的,下面的代码定义了一个Person类,并指定了一个主构造器。
class Person constructor (firstName:String)
如果主构造器没有任何的注释或修饰器,constructor关键字可以省略
class Person(firstName:String){ init{ println(firstName) } }
注意:如果是主构造器,需要在init构造块中进行初始化,在init块中,可以直接使用主构造器的参数。 java 代码:
classs Person{
public Persion(String firstName){
System.out.println(firstName)
}
}
注意:柱构造器的参数不仅可以用在init块中,还可以初始化类属性
- 第二构造器(可以声明若干个构造器,构造器前面必须加constructor)
class Person
{
contructor(parent :Person){
println(parent)
}
}
注意:
- 主构造器中参数可以使用var val,第二构造器不能使用var val,意思是第二构造器的参数是不可修改的,只能读
- 第二构造器中必须调用主构造器
//java的Singleton
class Singleton{
private static Singleton mInstance = new Singleton();
private Singleton(){
}
public Singleton getInstace(){
return mInstance;
}
}
//kotlin的单例模式
class Singleton private constructor(){
public var value:Singleton? = null;
private object mHolder {
var INSTANCE = Singleton()
}
companion object Factory{
fun getInstance:Singleton{
return mHolder.INSTANCE
}
}
}
var obj1 = Singleton.getInstance()
java与kotlin实现的方式不同(差别很大),主要原因是kotlin不支持静态方法和变量,由于kotlin支持全局函数和变量,所以可以用这个替代静态方法和变量
kotlin中Objects可以解决没有static引起的麻烦
kotlin函数中的默认参数
kotlin可以在主构造中设置默认参数的,java是不可以的
class Customer (val customerName : String = "bill",var value : Float = 20.4F)
{
}
创建类的实例kotlin可以省略new关键字,
类成员
var修饰的是变量,val修饰的是常量
kotlin的属性
var/val propertyName:propertyType = propertyinitializer
getter
setter
只有var/val propertyName是必须的,其他的都是可选的
####属性的getter和setter
如果getter或settter中只有一行代码,可以用“=”分隔开即可,如果是多行需要用{}
class Customer
{
val name :String
//only read
get() = "bill"
//read and write
var v:int = 2
get() = v
set(value){
print("dkdkkddk")
v = value
}
}
####通过field保存属性值的字段
class Customer{
val name : String
get() = "bill"
var value :String
get() = field
set(value){
print("dkdkdkd")
field = value
}
}
####函数
在kotlin中函数既可以在类的外部中定义,也可以在类的内部中定义,如果是前者则为全局函数,如果是后者则为类的成员函数,无论哪里定义,语法规则是一样的
- 函数也是可以有默认值的,如果有默认值则必须写在参数的后面
class QACommunity{
fun printQACommunity(url : String,schema:String = "https"){
println("${schema}://${url}")
}
}
// invoke like this
QACommunity().printQACommunity("www.baidu.com")
调用函数,只修改指定的默认值,可以如下调用
Person().process(30,"bill",salary = "100万/年")
可变参数的声明(vararg)
class Person (name:String){
private var nName :String = name
fun getName() :String
{
return mName
}
}
class Persons
{
fun addPersons(vararg persons:Person):List<Person>{
val result = ArrayList<Person>()
for(person in persons){
result.add(person)
return result
}
}
}
- 如果kotlin函数体中只有一行代码,可以直接在函数声明后加等于("="), 后面直接加代码,这种表达方式可以省略函数返回值类型。
修饰符(修饰符)
//"open" express Outer class can be extended
open class Outer{
private val a= 1
protected val b = 2
internal val c = 3
val d = 4 //default modifier is public
protected class Nested
{
public val e:Int = 5
}
}
class Subclass :Outer (){
//can not be access super class "a" val
//b c d e can be accessed
override val b = 5
}
类的继承
- kotlin 默认也只能单继承用的是冒号,java用的是extended
- kotlin 默认的类是不允许继承的,需要用open关键字显示声明
重写方法
open class Parent
{
protected var mName:String = "bill"
// only open added could be extended
open fun getName() :String
{
return mName
}
}
open class child :Parent{
override fun getName():String{ //如果禁止子类重写本方法,在这行最前面加final
return "[" + super.getName() + "]"
}
}
重写属性
属性与方法类似,被重写的属性必须用open声明,子类中重写的属性必须用override声明,val属性可以被重写为var,返过来不可以
open class Parent {
open val name:String = "bill"
get(){
println("”获取 Parent.name 属性值”")
return field
}
}
open class child :Parent(){
override var name:String = "tom"
get(){
println (”获取 Child.name 属性值”)
return field
}
set(value){
field = value
println (”Child.name 被写入”)
}
}
fun main(args:Array<String>){
var child= Child()
}
接口
- 接口中的属性和方法都是open的
//感觉有点像java的抽象类 interface MyInterface{ fun process() fun getName(){ // 可以不用重写此方法 return "bill" } }
小结
如果从作用上来说, Kotlin 中的类和接口与 Java 的类和接口 没什么本质上的差异,只不 过 Kotiin为了体现差异,加了一些语法糖,如接口允许函数带函数体,支持类属性,不支持静 态方法等。这些改进到底好不好,仍然需要时间去证明。不过既然 Kotlin 提供了这些功 能,我 们不妨去尝试一下,看看是否能给我们的开发工作提供便利 。