if we have a base class with a property like: ```...
# announcements
g
if we have a base class with a property like:
Copy code
var parent: MyAbstractClass? = null
how can I override this property in some of the concrete class to have something like:
Copy code
override var parent: MyConcreteClass? = null
I know that is possible to override properties, but it looks like kotlin do not understand that the MyConcreteClass is a supertype coming from the MyAbstractClass. Is there a way to get around this?
🎉 1
i
abstract var/val or open var/val
a
You cannot override a
var
with a subclass, the following code would fail at runtime:
Copy code
abstract class MyAbstractClass

class MyConcreteClass : MyAbstractClass()

class MyConcreteClass2 : MyAbstractClass()

open class BaseClass {
    var parent: MyAbstractClass? = null
}

class SubClass : BaseClass() {
    override var parent: MyConcreteClass? = null
}

val subClass: BaseClass = SubClass()
subClass.parent = MyConcreteClass2() //Is allowed, but fails at runtime
i
Copy code
abstract class BaseClass {
    open val someProp = 1337
    abstract var someVar: String
}

class DerivedClass: BaseClass() {
    override val someProp = 42
    override var someVar = "Hello, World!"
}
a
@Icaro Temponi he wants to override a property with a subclass of the property
i
oh, sry, i misunderstood the question 😥
g
When using your solution, my case is a little more complicated because it has a generic (<Something>). But copying your code, the strange is I receive the following error:
Copy code
Var-property type is 'MyConcreteClass?', which is not a type of overridden

public open var parent: MyAbstractClass? defined in …BaseClass
It’s not needed to me use this line:
Copy code
subClass.parent = MyConcreteClass2()
But this one will be fine:
Copy code
subClass.parent = MyConcreteClass()
Should I get the error above? I’m using IntelliJ
a
the error is fine. just because you don't need it doesn't mean you wouldn't run into this problem by accident in the future
so kotlin prohibits this case altogether
g
The funny thing is that I’ve found a way to put it to work. I used the
abstract
and I changed
MyAbstractClass?
to something like
Entity
(a generic that I’m already using). And it works 😃
Copy code
@MappedSuperclass
abstract class AbstractTestEntity<Entity : EntityInterface<Entity>> : AbstractEntity<Entity>() {

       ...

       abstract var parent: Entity?

        ...

}
where Entity is a generic, so in the concret class I’ve put
Copy code
@Entity
@Table(name = "tests")
class TestEntity : AbstractTestEntity<TestEntity>() {

       ....

        @JsonIgnore
	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "parent_id", insertable = false, updatable = false)
	override var parent: TestEntity? = null

        ...

}
I need the generic for other things, but it helped 😃
a
This version is different, because the class of the property doesn't change, its just generic
because
TestEntity<MyConcreteEntity>
can only be used as a
AbstractTestEntity<MyConcreteEntity>
, not as
AbstractTestEntity<MyAbstractEntity>