Kotlin课堂基础

时间:2018-07-14 15:42:26

标签: kotlin

我正在尝试使某些生产Java适应Kotlin,但是我不得不把它降低一个档次,因为显然我什至都无法弄清基础知识。

Java:

public class Person {
    private String name;
    public Person(String name) { this.name = name; }
    public String getName() { return name; }
    public static void main(String[] args) {
        Person p = new Person("me");
        System.out.println(p.getName());
    }
}

您将如何在Kotlin中做到这一点?也许只有这样:

// Person.kt
open class Person(var name: String)

$ kotlinc Person.kt && javap -p Person.class
Compiled from "Person.kt"
public class Person {
  private java.lang.String name;
  public final java.lang.String getName();
  public final void setName(java.lang.String);
  public Person(java.lang.String);
}

整洁,所以让所有自动生成的东西都可以使用:

open class Person(var name: String)
fun main(args: Array<String>) {
    val p = Person("me")
    println(p.getName())
}

$ kotlinc Person.kt 
Person.kt:4:15: error: unresolved reference: getName
    println(p.getName())
              ^

出什么问题了? p.name可以工作,但是我猜那是因为它们都在同一文件中。哎呀,我什至无法测试这是真的:

// PersonDemo.kt in same dir as Person.kt
object PersonDemo {
    fun main(args: Array<String>) {
        val p = Person("me")
    }
}

$ kotlinc PersonDemo.kt || (kotlinc Person.kt && kotlinc PersonDemo.kt)
PersonDemo.kt:3:17: error: unresolved reference: Person
        var p = Person("me")
                ^
PersonDemo.kt:3:17: error: unresolved reference: Person
        var p = Person("me")
                ^

也许可以导入?不,也不是。

清理classesproperties文档是没有用的,所以有人可以告诉我如何完成这些基本操作吗?

3 个答案:

答案 0 :(得分:2)

只需在Person类中编写以下代码并运行它即可。

// Person class in Kotlin
class Person(name:String) {
    val name:String
    // initializing name variable
    init {
        this.name = name
    }
    // main method converts to this in Kotlin
    companion object {
        @JvmStatic fun main(args:Array<String>) {
            val p = Person("me")
            println(p.name)
        }
    }
}

我们可以在这里删除初始化过程,因为我们可以直接从主构造函数访问name变量。因此,上面的Kotlin代码可以优化为:

class Person(val name: String) {

    // main method converts to this in Kotlin
    companion object {
        @JvmStatic fun main(args:Array<String>) {
            val p = Person("me")
            println(p.name)
        }
    }

}

答案 1 :(得分:2)

您不能使用getName,因为与Java相比,Kotlin在类属性上有一些不同的方法,在Java中,通常具有 getter setter的私有属性用于访问的方法,在Kotlin中其标准具有属性。

有2种属性:

  1. 使用var声明的变量使它们可变,并且可以更改其值,此属性具有与它们关联的两个方法setget
  2. val声明的那些使其不可变,因此它们的值无法更改,因为它们无法更改,因此它们仅具有get方法。

上面提到的getset方法不需要指定。

因此,遵循Kotlin课:

open class Person(var name: String,val id: Int)

等效于以下Java类:

public class Person {

    private String name;
    private final int id;

    public Person(String name, int id){
        this.name = name;
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    public int getId() {
        return id;
    }
}

请注意,id val ,因此它只有 getter

每个属性在Kotlin中默认为public,可以像在Java中一样在构造函数内部或类内部声明它们。当我们想要更改与该属性关联的get和/或set的默认行为时,使用最后提及的声明方法。

现在让其他人更好地解释这一点,让我举一个例子,让我们假设我们有上面使用过的类人,但是我们需要在每个名称前加上“名称:”。

在Java中,我们将通过以下方式重写上述 getter

public String getName() {
    return "Name: " + name;
}

要在Kotlin中获得相同的东西,我们需要编写如下内容:

open class Person(name: String,val id: Int){
    var name: String = name
        get() = "Name: $field"
}

请注意,我们没有在name中使用get,而是使用field来引用我们的媒体资源,同样重要的是要注意我们没有写{{ 1}}或val作为构造函数中的名称,这意味着它将只是常规参数。

关于属性的技巧很多,例如拥有var但将var设为私有,这样您就只能在该类内部更改值,后期初始化的属性等等。

作为答案的最后一部分,让我们看看如何使用 KOTLIN 编写的课程。

如果我们使用Kotlin代码中的该类:

set

在Java中使用相同的类:

val person = Person("KotlinPerson", 123)
person.name = "John"
val personName = person.name
val personId = person.id

最后,我也将添加相反的方法,您可以从上述代码中创建Person.java,并且Kotlin中的代码仍然可以正常工作,唯一的区别是使用Java代码时,您会得到{{1} },因为Java不保证某些值不为空。

答案 2 :(得分:0)

  

您将如何在Kotlin中做到这一点?

<exclusion>
    <groupId>org.junit</groupId>
    <artifactId>com.springsource.org.junit</artifactId>
</exclusion>