How to get new variable value from inherited class? - kotlin

open class Parent(){
protected var z : Int? = null
private fun getMyAge(){
val x = 65
val y = 10
z = x % y
}
}
class Child:Parent(){
ovveride fun getMyAge()
println(z) //here I get null
}
My question is: why I get null?
Am I getting a variable from an inherited class incorrectly?

It's because when you override the function, the super function is not called. If you want the function in parent class called, you must change your code to this:
open class Parent(){
protected var z : Int? = null
private fun getMyAge(){
val x = 65
val y = 10
z = x % y
}
}
class Child:Parent(){
ovveride fun getMyAge()
super.getMyAge()
println(z)
}

Related

Confusion about fileds and get methods in Kotlin

Since A is a property and not a field, does that mean that A and B are functioning exactly the same way? If not, what are their difference?
class myClass(val x : Int, val y : Int){
val A = x * y
val B :Int
get(){
return x * y
}
}
In this specific example, a property with a backing field (A) and a property without a backing field (B) work exactly the same, because x and y are vals and their values can't be reassigned - no matter how many times you compute x * y it'll always return the same result. But consider the following program:
class myClass(var x : Int, val y : Int){
val A = x * y
val B :Int
get(){
return x * y
}
}
fun main() {
val myClass = MyClass(x = 2, y = 3)
println(myClass.A) // 6
println(myClass.B) // 6
myClass.x = 4
println(myClass.A) // 6
println(myClass.B) // 12
}
x is a var now, which means that its value can be changed. The value of A has already been computed when the instance of MyClass was created, so changing the value of x has no effect on the value of A. But since accessing B executes the body of its getter every time, a change in the value of x will affect the result of the next call to that getter.

Best way to hide internal classes by interfaces

what is the best way to hide an impl class behind an interface?
The companion creator works well, but needs to repeat all the arguments of the constructor twice.
Is there a way to simplify A.from(x,y,z,a,b,c,d) = AImpl(x,y,z,...)?
//the application will only see this interface
interface A {
val x: X
val y: Y
companion object {
//choose any implementation without breaking existing code
#JvmStatic
fun from(x: X, y: Y): A = AImpl(x = x, y = y) //inconvenient for many arguments
}
}
internal class AImpl(
override val x: X,
override val y: Y
) : A
fun someApplication() {
val a = A.from(..., ...) //no reference to AImpl
//use a: A
}
Thank you very much.
Martin
The way you wrote it is already good. If you're concerned about too many parameters, note that you don't have to name and pass every single one of them, and not every property needs to be passed as a constructor parameter. Depending on the implementation class, some properties can be defaulted or calculated:
interface A {
val x: X
val y: Y
companion object {
fun from(x: X, y: Y): A = AImpl(x)
}
}
internal class AImpl(
override val x: X,
) : A {
override val y = something()
}
Furthermore, AImpl doesn't have to be internal; it can be private or even an anonymous class, if it's a very short one (otherwise the code can become unreadable):
interface A {
val x: X
val y: Y
companion object {
fun from(x: X, y: Y): A = object : A {
override val x = x
override val y = y
}
}
}
Instead of using a member function of a companion object, a common Kotlin-idiomatic way is to use a standalone factory function with the same name as the interface:
fun A(x: X, y: Y): A = AImpl(x, y)
An example of such a function is MutableList: it has the same name as interface MutableList, and it happens to return an ArrayList but that's just implementation detail: it's only documented to return something that implements interface MutableList.
I don't really understand what are you tring to do.
So i'm not sure if this will be the answer to your question.
fun main() {
val x = X()
val y = Y()
val a = AImpl().from(x,y)
a.x.toString()
a.y.toString()
//use object class so you can use the class without ()
val b = BImpl.from(x,y)
b.x.toString()
b.y.toString()
}
class X{}
class Y{}
interface A
{
val x : X
val y : Y
fun from(xValue : X, yValue : Y) : A
}
internal class AImpl() : A {
override var x : X = X()
override var y : Y = Y()
override fun from(xValue : X, yValue : Y) : A {
x = xValue
y = yValue
return this
}
}
object BImpl : A {
override var x : X = X()
override var y : Y = Y()
override fun from(xValue : X, yValue : Y) : A {
x = xValue
y = yValue
return this
}
}
I don't think you should implementation anything in Interface
but If you want your code to work
companion object {
//choose any implementation without breaking existing code
#JvmStatic
//fun from(x: X, y: Y): A = AImpl(x = x, y = y)
//because you Return A That's why you got no reference to AImpl
//so don't return A but make it AImpl directly
//but it's still act like "A" interface.
fun from(x: X, y: Y) = AImpl(x,y)
}
}

Re-initialize object properties in Kotlin

I often have a class with properties that are initialized at instantiation, like
class C {
var x = 10
var y = v * 2 // v is some variable
}
val c = C()
then properties of c are changed, and later I need to re-initialize the properties (so that c.x is 10 again and c.y is v*2, where the value of v may have changed).
My current approach is to initialize the properties with dummy values (or alternatively use lateinit and type annotations), and assign the desired values in an extra function ini like
class C {
var x = 0
var y = 0
init {
ini()
}
fun ini() {
x = 10
y = v * 2
}
}
then I call c.ini() to re-initialize.
Is there a better (more succinct) way that avoids the dummy values?
Note that in JavaScript I can simply write
class C {
constructor() {
this.ini()
}
ini() {
this.x = 10
this.y = v * 2
}
}
What you are doing right now is totally fine. I wouldn't change it.
If you want to avoid the placeholder values of 0, or if the type of the property has no placeholder value that make sense, you can store the initial values in private lambdas:
class C {
private val xInit = { 10 }
private val yInit = { v * 2 }
var x = xInit()
var y = yInit()
fun reset() {
x = xInit()
y = yInit()
}
}
If you really want to reduce the boilerplate, I can only think of this rather hacky and slow solution that relies on reflection. This could be usable if the instances don't need to be reset that often, and you have lots of these classes with resettable properties, and you just hate writing boilerplate reset methods.
class Resettable<T>(val supplier: () -> T) {
var wrapped = supplier()
operator fun getValue(thisRef: Any?, property: KProperty<*>): T {
return wrapped
}
operator fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
wrapped = value
}
fun reset() {
wrapped = supplier()
}
}
fun <T: Any> T.reset() {
// look for properties delegated with Resettable
this::class.memberProperties.mapNotNull {
it.isAccessible = true
(it as KProperty1<T, *>).getDelegate(this)
}.filterIsInstance<Resettable<*>>().forEach {
it.reset()
}
}
Now you just need to do:
var v = 10
class C {
var x by Resettable { 10 }
var y by Resettable { v * 2 }
}
fun main() {
val x = C()
println(x.y) // 20
v = 20
x.reset()
println(x.y) // 40
v = 40
x.reset()
println(x.y) // 80
}
Note that the first reset call would load all the kotlin reflection classes, and would take a noticeable amount of time.

Object expressions, Multiple supertype specification syntax?

I am new to Kotlin. I came across the Object Expressions section of https://kotlinlang.org
Some of the object expression syntaxes are very straight forward to understand,
Create an object of an anonymous class
window.addMouseListener(object : MouseAdapter() {
override fun mouseClicked(e: MouseEvent) { ... }
override fun mouseEntered(e: MouseEvent) { ... }
})
Just an object
fun foo() {
val adHoc = object {
var x: Int = 0
var y: Int = 0
}
print(adHoc.x + adHoc.y)
}
But I am unable to understand the "Object expression with multiple supertypes specified" example given as below:
open class A(x: Int) {
public open val y: Int = x
}
interface B { ... }
val ab: A = object : A(1), B {
override val y = 15
}
What's happening here?
${ab.y} prints 15
but syntax -> ${ab.A.y} is not valid. My understanding of ${ab.A.y} it will print 1 :)
This line here:
val ab: A = object : A(1), B {
means that the class of ab is inherited from class A and implements interface B.
Actually the code example you gave will only compile if you declare and implement the interface. This is a possible implementation:
open class A(x: Int) {
public open val y: Int = x
}
interface B {
fun hi()
}
val ab: A = object : A(1), B {
override val y = 15
override fun hi() {
println("hi")
}
}
The expression ${ab.A.y} does not make much sense in this context, because the object ab does not have any field A. A is just the inherited superclass to which you could eventually cast.
It basically creates object ab with class type A with implementation of interface B.
So, let's say your class A has some method foo() & interface B has some method bar(), you can access them both on object ab as it's of class type A with implementation of B.
Hence, here you override variable y with value 15 meaning your superclass variable y will get overridden by value 15 from 1.

How to implement an abstract getter with property

I have java code:
public abstract class A {
abstract int getA()
}
I tried:
class B : A() {
val a = 0
}
Doesn't compile.
class B : A() {
override val a = 0
}
Still doesn't compile.
class B : A() {
override val a: Int get () = 1
}
Still doesn't compile.
class B : A() {
override val a: Int override get () = 1
}
Still doesn't compile.
class B : A() {
val a: Int override get () = 1
}
None of them are working. Does that mean I can only use
class B : A() {
override fun getA() = 1
}
? I think the last one(overriding the method) is ugly.
This could be worse when you have a getter-setter pair. It's expected to override getter-setter pair with a var property, but you have to write two methods.
According to #Miha_x64 ,
functions can be overriden only with a function.
Seems that I was trying something impossible.