我正在尝试使一些产品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")
^可能是导入?不,也不是那样。
搜索classes和properties文档是没有用的,那么,谁能告诉我这些基本的东西是如何完成的?
发布于 2018-07-14 23:52:59
只需在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)
}
}
}发布于 2018-07-15 01:25:52
你不能使用getName,因为与Java相比,Kotlin处理类属性的方法有点不同,在Java语言中,拥有私有属性和用于访问的getter和setter方法是标准的,在Kotlin中,它的标准是拥有属性。
有两种属性:
对于那些用var声明的方法,它们的值是可变的,并且它们的值可以改变,这个属性有两个方法与它们关联,set和用val声明,这使得它们的值是不可变的,所以它们的值不能改变,因为它们只有get方法与之关联。
上面提到的get和set方法不需要指定。
下面是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的默认行为时,使用最后提到的声明方法。
现在为了更好地解释这一点,让我给你一个例子,假设我们有上面使用的person类,但我们需要在每个名字前面加上" name:“前缀。
在Java中,我们会用下面的方式重写上面提到的getter:
public String getName() {
return "Name: " + name;
}在其他情况下,要在Kotlin中获得相同的内容,我们需要编写如下代码:
open class Person(name: String,val id: Int){
var name: String = name
get() = "Name: $field"
}注意,我们没有在get中使用name,而是使用field来引用我们的属性,同样重要的是,我们没有在构造函数中为name编写val或var,这意味着它将只是常规参数。
关于属性还有很多巧妙的技巧,比如让var变成私有的set,这样你只能在类内部修改值,后期初始化的属性等等。
作为我答案的最后一部分,让我们看看如何使用我们用KOTLIN编写的类。
如果我们使用Kotlin代码中的类:
val person = Person("KotlinPerson", 123)
person.name = "John"
val personName = person.name
val personId = person.id使用相同的类,但在Java中:
Person person = new Person("JavaPersonFromKotlinClass", 123);
person.setName("John");
String personName = person.getName();
int personId = person.getId();最后,我要补充的是,相反的情况也适用,你可以从上面的代码生成Person.java,而用Kotlin编写的代码仍然可以很好地工作,唯一的区别是,当使用Java代码时,你会得到String?,因为Java不能保证某些值不是空的。
发布于 2018-07-15 01:31:00
你如何在Kotlin中做到这一点或类似的事情?
class Person(val name: String) {
companion object {
@JvmStatic fun main(args: Array<String>) {
val p = Person("me")
System.out.println(p.name);
}
}
}https://stackoverflow.com/questions/51340946
复制相似问题