I have a class in Kotlin:
class AClass {
companion object {
const val CONST_VAL = "THIS IS A CONST VAL STRING"
val JUST_VAL = "THIS IS A NON-CONST VAL STRING"
fun aFunction() {}
}
}
and a Main class in Java which is accessing companion members:
public class Main {
public static void main(String[] args) {
// aFunction can only be accessed by using Companion
AClass.Companion.aFunction();
// CONST_VAL can only be accessed from the parent class
String constValString = AClass.CONST_VAL;
// JUST_VAL can only be accessed with Companion
String valString = AClass.Companion.getJUST_VAL();
}
}
How come, in Java, both #aFunction() and JUST_VAL can only be accessed via the Companion while CONST_VAL can only be accessed via the parent class directly? Shouldn't CONST_VAL be accessed only via the Companion as well?
Related
I have a Parent class written in Java file
public class ParentClass {
public static int method1() {
return 1;
}
}
I have a Child class written in kotlin
class ChildClass: ParentClass() {
companion object {
#JvmStatic
fun childMethod1(): Int {
return 100
}
}
}
Similarly, I have a child class written in Java
class JavaChildClass extends ParentClass {
public static int childMethod1() {
return 200;
}
}
Now, in my main kotlin class, I am trying to access the methods,
val result1 = JavaChildClass.childMethod1() //Method in the Java child class
val result2 = JavaChildClass.method1() //Method in the parent class
val result3 = ChildClass.childMethod1() //Method in Kotlin Child class
val result4 = ChildClass.method1() //Error, cannot access this method
In java class with annotation:
public final class Info {
private Info() {
}
public static class InfoAction {
public static final String OPEN = "open";
public static final String VIEW_ALL = "view_all";
#Retention(RetentionPolicy.SOURCE)
#StringDef({OPEN, VIEW_ALL})
public #interface Action {
}
public String mAction;
public InfoAction(#Action String action) {
this.mAction = action;
}
}
IDE convert to kotlin:
class Info private constructor() {
class InfoAction(#param:Action var infoAction: String) {
#kotlin.annotation.Retention(AnnotationRetention.SOURCE)
#StringDef(OPEN, VIEW_ALL)
annotation class Action
companion object {
const val OPEN = "open"
const val VIEW_ALL = "view_all"
}
}
}
it has #param:Action, but replace with #Action it works as well.
what is this #param here for, and can the #Action be used?
#param is for constructor parameter
detail:
https://kotlinlang.org/docs/annotations.html#annotation-use-site-targets
interface SomeInterface {
fun someFunction()
}
class SomeClass(private val someInterface: SomeInterface) {
}
What does it mean? As far as I know, interface can't instantiate objects and if it can then where should I implement someFunction()?
You are correct that you cannot instantiate SomeInterface directly, but you can pass implementations of your interface to SomeClass. This way SomeClass can use someFunction() but doesn't care about the lower-level implementation details of the interface (aka polymorphism).
interface SomeInterface {
fun someFunction()
}
class SomeClass(private val someInterface: SomeInterface) {
fun doSomething() = someInterface.someFunction()
}
class SomeImplementation(): SomeInterface {
override fun someFunction() {
println("did something")
}
}
fun main() {
val someClass = SomeClass(SomeImplementation())
someClass.doSomething()
}
Just reading some Kotlin code and notice that we can define properties either in (...) or in {...}.
class Foo(val name: String = "Yuchen") {
val name2: String = "Zhong"
}
fun main(args: Array<String>) {
val foo = Foo()
println(foo.name)
println(foo.name2)
}
What're their differences and when should we use which?
If you transform kotlin code to java using bytecode decompiler you will get that one.
class InitOrderDemo(val name: String = "Yuchen") {
val name2: String = "Zhong"
}
Decompiled java code:
public final class InitOrderDemo {
#NotNull
private final String name2;
#NotNull
private final String name;
#NotNull
public final String getName2() {
return this.name2;
}
#NotNull
public final String getName() {
return this.name;
}
public InitOrderDemo(#NotNull String name) {
Intrinsics.checkParameterIsNotNull(name, "name");
super();
this.name = name;
this.name2 = "Zhong";
}
....
}
Notice, please, that name argument you can pass through constructor invoke, but name2 couldn't be changed - it's similar to constant here.
So if you want property to be immutable (but not constant for all instances of that class), you will need define it in () - in constructor.
I'm new to Kotlin and I'm trying to use it in my Android project. I have this code:
public var oneTouchTimer: CountDownTimer = CountDownTimer(500, 100) {
override fun onTick(l: Long) {
}
override fun onFinish() {
}
}
And it's throwing the error:
Cannot create an instance of an abstract class.
Basically I'm trying to create an instance of CountDownTimer and cannot figure out how to convert it to Kotlin.
Here is the code in Java:
CountDownTimer oneTouchTimer = new CountDownTimer(500, 100) {
#Override
public void onTick(long l) {
}
#Override
public void onFinish() {
}
};
You can use this method:
var variableName = object: CountDownTimer(...){
...
}
These are called "object expressions" in Kotlin. The docs are available here: Object expressions
Just makes sure you have compatible data types