Ответ 1
Создание этой переменной private
решает проблему.
public class KotlinClass(private val name: String?) : JavaInterface
С приведенным ниже кодом я получаю следующую ошибку в IntelliJ IDEA 13.1.6 и плагине Kotlin 0.11.91.AndroidStudio.3:
Platform declaration clash: The following declarations have the same JVM signature (getName()Ljava/lang/String;):
• public open fun getName(): kotlin.String?
• internal final fun <get-name>(): kotlin.String?
Класс Java, JavaInterface.java
:
public interface JavaInterface {
public String getName();
}
Класс Котлина, KotlinClass.kt
public class KotlinClass(val name: String?) : JavaInterface
Я попробовал переопределить метод getter
добавив override fun getName(): String? = name
, но это приводит к той же ошибке.
Я вижу одно обходное решение, делая это вместо этого:
public class KotlinClass(val namePrivate: String?) : JavaInterface {
override fun getName(): String? = namePrivate
}
Но в моем реальном случае у меня есть ряд свойств для реализации и нуждающихся в настройках. Делать это для каждого свойства не кажется очень Kotlin-ish. Что мне не хватает?
Создание этой переменной private
решает проблему.
public class KotlinClass(private val name: String?) : JavaInterface
Еще одна задача - объявить свойства абстрактного класса Kotlin, а затем написать небольшой класс java, который расширяет KotlinClass и реализует JavaInterface.
// JavaInterface.java
public interface JavaInterface {
int getFoo();
void setFoo(int value);
}
// KotlinClass.kt
abstract class KotlinClass(open var foo : Int = 0) {
}
// JavaAdapter.java
class JavaAdapter extends KotlinClass implements JavaInterface {
// all code in KotlinClass, but can't implement JavaInterface there
// because kotlin properties cannot override java methods.
}
Вы можете использовать @JvmField для указания компилятору не генерировать getter/setter, и вы можете реализовать свои сеттеры и геттеры. Благодаря этому ваш код хорошо работает на Java (в качестве атрибута getter/setter) и Kotlin as property
Пример: JAVA
public interface Identifiable<ID extends Serializable>
{
ID getId();
}
Котлин
class IdentifiableImpl(@JvmField var id: String) :Identifiable<String>
{
override fun getId(): String
{
TODO("not implemented")
}
}
Если у вас есть прямой контроль над интерфейсом, лучший подход - написать интерфейс в Kotlin. Затем вы можете написать свой класс
public class KotlinClass(override val name: String?) : KotlinInterface
и по-прежнему ссылаться на него с любого Java-кода, используя тот же интерфейс, что и раньше. Это выглядит намного опрятно, чем установка всех свойств в частные и переопределение функции get. Очевидно, что если вы не можете перенести интерфейс на Java, потому что вы его не владеете, это единственное решение.
Мы обнаружили, что для использования одинаковых имен без столкновения ctor args должен быть private. И вы должны по-прежнему переопределять методы интерфейсов. Вам не нужны дополнительные поля поддержки. Кроме того, назначение тела выражения не будет возвращаться, поэтому вы можете безопасно использовать этот синтаксис.
Интерфейс Java
interface IUser {
String getUserScope();
String getUserId();
}
Класс Котлина
class SampleUser(private val userScope: String, private val userId: String) : IUser {
override fun getUserId() = userId
override fun getUserScope() = userScope
}
ИМХО наиболее читаемым сочетанием является реализация поля + явного интерфейса с помощью функции с одним выражением (комбинация ответов @Renato Garcia и @Steven Spungin):
Джава:
public inteface SomeInterface {
String getFoo();
}
Котлин:
class Implementation(@JvmField val foo: String) : SomeInterface {
override fun getFoo() = foo
}
public interface JavaInterface {
public String getName();
}
public class KotlinClass(val namePrivate: String?) : JavaInterface {
private var name = namePrivate
override fun getName(): String? {
return name
}
}
Переименуйте переменную в другое или сделайте ее закрытой, если вы не хотите, чтобы она была публичной.
мы можем это сделать!
package com.example.mykotlin
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
tv.text = "Hello MyKotlin"
tv.textSize = 20.0f
}
}