Kotlin abstract class must have constructor and get initialized - kotlin

When I have this class hierarchy:
SUPERCLASS
abstract class AbsSuperClass {
abstract fun someFun()
}
SUBCLASS
class Subclass : AbsSuperClass {
override fun someFun()
}
I get an IDE error in the subclass saying:
This type has a constructor, and thus must be initialized here
But doesnt this counter the whole argument of having abstract classes? I just DONT want the abstract class to be initialized

You have just forgotten () in your class extension:
class Subclass : AbsSuperClass() {
override fun someFun()
}

Related

Kotlin concrete class extending from abstract class and interface, with the interface using a method implemented in the abstract class

I want to ask a question that I have some clues about, but I don't want to influence the answers I will get. I have the following class hierarchy:
abstract class MyAbstractClass {
fun displayStuff(id: String) {
println("My id is $id.")
}
}
interface MyInterface {
fun displayThis() {
displayStuff("some-value")
}
fun displayStuff(id: String) // Not implemented here
}
class MyConcreteClass(): MyAbstractClass(), MyInterface {
fun doStuff() {
displayThis()
}
}
fun main() {
val result = MyConcreteClass()
result.doStuff()
result.displayStuff("id")
}
What's wrong with this design, and how do you suggest I fix it?
It would probably not be a bad idea to extract the displayStuff into another interface. Then MyAbstractClass and MyInterface can both derive from the same interface.
One overrides the displayStuff function, hence providing something like an abstract base implementation for the interface.
The other one is using the function in a specific way, thereby extending the functionality of the interface.
interface DisplayStuff {
fun displayStuff(id: String)
}
abstract class MyAbstractClass: DisplayStuff {
override fun displayStuff(id: String) = println("My id is $id.")
}
interface MyInterface : DisplayStuff {
fun displayThis() = displayStuff("some-value")
}

in kotlin, how to access protected static member in parent class from sub class

It is code worked in java but after convert to kotlin it does not compile.
Having a base class which has some defines as static protected member in the companion object:
abstract class ParentClass {
companion object {
#JvmField
final protected val SERVICE_TYPE_A = "the_service_type_a"
}
}
and the child class:
class ChildClass: ParentClass {
public override fun getServiceType(): String {
return SERVICE_TYPE_A. //<== got compile error
}
}
it does not compile.
how to access a parent class static protected member from subclass?
You need to use #JvmStatic instead as follows:
abstract class ParentClass {
companion object {
#JvmStatic
protected val SERVICE_TYPE_A = "the_service_type_a"
}
abstract fun getServiceType(): String
}
The final keyword in SERVICE_TYPE_A is redundant since everything is final by default in Kotlin. This also mean that if you want ParentClass to be extended, then you need to explicitly define it as open.
Then your ChildClass would look as follows:
class ChildClass: ParentClass() {
override fun getServiceType(): String {
return SERVICE_TYPE_A
}
}

Can a abstract class include non-abstract class parameter in Kotlin?

The Code A is from the aritcle https://developer.android.com/training/dependency-injection/hilt-android
In my mind, a abstract class can not include non-abstract class .
But the function abstract fun bindAnalyticsService( analyticsServiceImpl: AnalyticsServiceImpl): AnalyticsService accept a non-abstract class parameter, why?
Code A
interface AnalyticsService {
fun analyticsMethods()
}
// Constructor-injected, because Hilt needs to know how to
// provide instances of AnalyticsServiceImpl, too.
class AnalyticsServiceImpl #Inject constructor(
...
) : AnalyticsService { ... }
#Module
#InstallIn(ActivityComponent::class)
abstract class AnalyticsModule {
#Binds
abstract fun bindAnalyticsService(
analyticsServiceImpl: AnalyticsServiceImpl
): AnalyticsService
}

Ensure KClass of class that implements interface

I have a custom converter annotation like:
#Target(AnnotationTarget.FIELD, AnnotationTarget.PROPERTY)
#Retention(AnnotationRetention.RUNTIME)
#MustBeDocumented
annotation class CustomConverter(val converter: KClass<*>)
And I have an interface:
interface FooConverter<T> {
fun from(str: String): T?
fun to(value: T): String
}
And I have a class implementing this interface:
class BarConverter : FooConverter<Int> {
// Implementation
}
And I use the annotation like:
class MyDTO {
#CustomConverter(BarConverter::class)
var myProp: Int? = null
}
Is there a way to ensure the KClass on the annotation has a class that implements the FooConverter<T> interface?
I have tried:
annotation class CustomConverter(val converter: KClass<FooConverter<*>>)
annotation class CustomConverter(val converter: KClass<FooConverter<Any>>)
but it doesn't work. The compiler complains.
Thanks!

override function with concrete type parameter

Hi I would like know why the following example doesn't work
abstract class BaseClass {
}
class ConcretClasOne : BaseCalculator {
}
class ConcretClasTwo : BaseCalculator {
}
abstract class BaseRun {
abstract fun run(param: BaseClass): Int
}
class ConcretRun : BaseRun {
override fun run(param: ConcretClasOne): Int {
return 0
}
}
this shows me a message run overrides nothing.
I suppose that kotlin isn't able to match the abstract class and the concrete implementation, but what other alternative is there to emulate this behavior, that the run method in the concrete class ConcretRun should receive a concrete param ConcretClasOne?
Generics
Using generics, you can make the base class have a type extending the base class, so that the run method can take that type in.
abstract class BaseClass {
}
class ConcretClasOne: BaseCalculator {
}
class ConcretClasTwo: BaseCalculator {
}
abstract class BaseRun<T: BaseClass> {
abstract fun run(param: T): Int
}
class ConcretRun: BaseRun<ConcretClasOne> {
override fun run(param: ConcretClasOne): Int {
return 0
}
}
Why your code doesn't work
At the moment you are trying to override a method with a more specific type, but as the more general base method can accept more types the more specific method cannot override it.