kotlin: how to use KProperty2? [closed] - kotlin

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed last year.
Improve this question
I understand that KProperty1 represents a property on a class, such as MyClass::myProperty.
I'm having trouble understand how KProperty2 should be used, or even what the concrete use case is for that pattern?
Thanks

It's as documentation states for properties that take two receivers like extension property declared in a class.
Do note that calling extension functions and properties declared within class has be done within that class itself or through scoping functions (as done in sample below with run {}):
Example:
data class Foo(val tag : String) {
val Int.echo
get() = "Im extension on $this within ${this#Foo}"
}
fun propTest(){
val foo = Foo("Baz")
foo.run {
println(5.echo) // prints Im extension on 5 within Foo(tag=Baz)
}
val tagRef : KProperty1<Foo, String> = Foo::tag
val echoRef : KProperty2<Foo, Int, String> = Foo::class.declaredMemberExtensionProperties.first() as KProperty2<Foo, Int, String>
println(echoRef.get(foo, 7)) // prints Im extension on 7 within Foo(tag=Baz)
}
I don't know if it's possible to directly reference those extensions (Int::echo within class scope just causes error) that's why I used declaredMemberExtensionProperties (which is actually a List<Kproperty2<Foo, *, *>>) to fetch it.

Related

Kotlin best practice of data structure with inheritance and required parameters? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 1 year ago.
Improve this question
Is there a possibility in Kotlin to construct an Object that allows sub-objects and where you are only allowed to construct the sub-objects and must pass obligatory parameters defined in the parent object and obligatory parameters defined in each sub-object?
I was thinking in a call like this:
val obj1 = TransferObject.TransferObject_ONE(system = "sys3", obligatoryString = "myString", amount = 12)
With a code like this:
enum class SupportedTypes {
ONE, TWO
}
sealed class TransferObject(
val type: SupportedTypes,
val system: String = "sys1",
val amount: String,
val awaitReceipt: Boolean = true
) {
data class TransferObject_ONE(
val obligatoryString: String
) : TransferObject(SupportedTypes.ONE)
data class TransferObject_TWO(
val obligatoryInt: Int
) : TransferObject(SupportedTypes.TWO)
}
But of course this won't work, do you have a recommendation, would maybe a factory be the ideal solution for this case?

When defining the behavior of an object, is it better to pass an anonymous object or a callback? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 1 year ago.
Improve this question
Let's say we have a class that performs some action on its own and receives the result.
// This class cannot be modified.
abstract class BaseWorker {
fun someWork() {
// blabla...
onComplete()
}
abstract fun onComplete()
}
I know there are two ways to freely override the behavior of onComplete in the above class.
// case1
fun main() {
object : BaseWorker() {
override fun onComplete() {
// blabla..
}
}.someWork()
}
// case 2
class Worker(val callback:()->Unit): BaseWorker {
final override fun onComplete() {
callback()
}
}
fun main() {
Worker(callback= { //blabla... }).someWork()
}
Either one works fine, but I'm not sure which of these two behaviors should be the way to go in Kotlin.
Can you provide an existing document or answer directly on this?
Both mentioned ways are correct and would work fine. So first thing you need to take into account - your team approach. It is better to use same way in all same situations.
Then there are some factors that should be mentioned:
If responsibility on what should happen is on the class outside the worker (in your case it seems to be the root class with main method), using callback is more handy. In this way it's easier to invoke various code on work completion.
If all the variability should be encapsulated in BaseWorker children, it's totally should be as implementation of an abstract method.

Kotlin Generic function type return child class [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
I am trying to create a class where generic operations can be performed on classes that has inherited from it. I have tried using sealed classes, inline functions to no success, hopefully someone can provide some insight on this.
Example
class Base {
fun add // does the operation
}
data class A(val a: Int, val b: Int) : Base
data class B(val c: Int, val d: Int) : Base
val example = A(1,2)
example.add(A(3,4))
println(example)
// A(4,6)
val example2 = B(5,6)
example2.add(B(7,8))
println(example2)
// B(12, 14)
What you're looking for is self-referential generics.
abstract class Base<B : Base<B>> {
abstract fun add(other: B): B
}
data class A(...) : Base<A>
data class B(...) : Base<B>

Should I initialize variables on declaration, init block, constructor or lateinit? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
Improve this question
I was wondering whats the difference between the 4 ways of initializing a variable (that I know of) in kotlin and which one would be the most accepted one.
First, initialize it on declaration:
class MyClass {
var textString: String = "Hello world"
}
Second, initialize it on the init block:
class MyClass {
var textString: String
init {
textString = "Hello world"
}
}
Third, use a constructor:
class MyClass {
var textString : String
constructor() {
this.textString = "Hello world"
}
}
Fourth, lateinit:
class MyClass {
lateinit var textString : String
fun initializeVariable() { //Assume this is called by something
this.textString = "Hello world"
}
}
I am mostly looking for the difference on compile time and the overall "good practice". I am aware of some "tricks" you can use, like using the init block to initialize some variables that are always the same regardless of the constructor used, but would that be the appropiate way of doing it?
From the technical standpoint, there's no much difference, at least in terms of simple properties like in the example - the property gets initialised anyway.
The lateinit modifier is a little exception here - it allows for a delayed initialization: it's like saying "I cannot set a meaningful value now, but I'm sure that it will be set before the first use". It is useful in Kotlin - Spring Framework integration, when one, for some reason doesn't want/cannot use constructor injection, and allows for property injection.
#Autowired lateinit var foo: Foo
or when using Spring's #Value annotation
#Value("\#{props.foo}") lateinit var foo: String
There's a difference, though, from the reader / maintainer point of view, and when you need some extra functionality, say precondition validation. As a rule of thumb initialise your properties as early as possible: the preferred way is in the primary constructor:
class Foo(var bar: String = "default value")
The reader of your code, maybe future you, won't have to jump trough the code to understand where does the "default value" come from - it's right in the constructor!
Additionally, client code, can easily change the value when constructing the object, or leave it default
// set new value
val foo: Foo = Foo(bar = "specific value other than default")
// leave the default
val defaultFoo: Foo = Foo()
Having the property initialised in class body, forces the client code to firstly create an instance with a default, and only then override.
val foo = Foo()
foo.bar = "not so default"
Additionally, if there're some preconditions which you like to check, it's easier to do this when setting the values in the primary constructor. E.g. the foo String property cannot be blank:
class Foo(var bar: String = "default") {
init {
require(bar.isNotBlank()) { "Bar cannot be blank" }
}
}
Where it's possible I'd go with constructor initialization.
Also, if you are willing to spend a few dollars on a book on good practices and patterns in Kotlin, I highly recommend Marin MoskaƂa's Effective Kotlin https://leanpub.com/effectivekotlin
lateinit is irrelevant because it doesn't initialize anything.
Initialization on the same line is only for simple properties. You can use closures and then invoke them, like so val i = { // complex code }(), but it's ugly.
For a detail discussion of constructor vs init block, see this. The simplest way to understand the initialization order is to create a class with a primary, secondary and an init block, and then either use println or simply a debugger to follow the execution.

Why abstract method cannot have an implementation inside the body? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I am having a problem that i have to implement the parent method and the method has to be overriden in the child class for further implementation.
Why this happen? and Why the language like Java, Typescript, C# do not allow this?
Since many of you ask why do i need it.
I have a parent class called Component written in typescript
class Component {
root : HTMLElement;
constructor(root : HTMLElement) {
this.root = root;
this.decorate();
}
abstract decorate();
}
class Field extends Component {
this.id;
constructor(root : HTMLElement) {
super(root);
}
decorate() {
this.id = this.root.getAttribute(data-id);
}
}
class InputField extends Field {
inputField : HTMLElement;
constructor(root : HTMLElement) {
super(root)
}
//i want to force users to override this
decorate(){
//and to call this
super.decorate();
this.inputField = this.root.getElementById('input-field');
}
}
Because abstract method purpose is to have its definition in super class and force child classes to override and implement it.
From Java Doc:
An abstract method is a method that is declared without an implementation (without braces, and followed by a semicolon), like this:
abstract void moveTo(double deltaX, double deltaY);
If you want to have an implementation in the abstract method you should not declare method as abstract and remember to override it in child classes calling super method if needed.