0

Here's an example:

abstract class Parent {
    constructor() {
        sayName()
    }

    abstract fun sayName()
}

class Child : Parent() {
    private var name: String = "Melina"
    
    override fun sayName() {
        if (name == null) name = "John"
        println(name)
    }
}

fun main() {
    println("Hello, world!!!")
    var child = Child()
    child.sayName()
}

Live: https://pl.kotl.in/vIuBzrBON

The problem: a sub class would like to override an abstract method and use a private var in that method. The subclass private var would normally be null in the parent class constructor, so I added the line

if (name == null) name = "John"

in order to define the value in that case. However, the subclass will still override the value "John" with the value "Melina".

How can we prevent the subclass from overriding the value, so that it will remain "John"?

I know I could put "Melina" in both places, but I am wondering if it is possible to not repeat the value.

trusktr
  • 44,284
  • 53
  • 191
  • 263
  • 4
    Calling open or abstract functions from the constructor is highly discouraged. I think it’s only allowed by the compiler for JVM compatibility with something that’s considered to be a design mistake in Java. More info: https://stackoverflow.com/questions/50222139/kotlin-calling-non-final-function-in-constructor-works – Tenfour04 Apr 24 '21 at 18:57

1 Answers1

0

Better not to call actions in the constructor.

Constructor is good place for initialize fields. If every child of Parent class should have name, you can declare it as field and set concrete value in child class. So call sayName() method after construction of object:

abstract class Parent {
    abstract val name: String
    
    abstract fun sayName()
}

class Child : Parent() {
    override val name: String = "Melina"
    
    override fun sayName() {
        println(name)
    }
}

If you use some framework for object creation, you can annotate your method with command to call this method after creation. For example, put @PostConstruct on method sayName() if you use Spring Framework.