Class is not abstract and does not implement abstract base class member - kotlin

I'm confused by this Kotlin error associated with providing an implementation for an abstract class that has been imported from a maven package.
I have a maven library that is written in Kotlin and exposes an abstract class called APIGatewayRequestHandler. In my app that imports the library, I provide an implementation of the abstract class:
class GetWelcomeMessageHandler : APIGatewayRequestHandler<WelcomeMessage>()
fun handleAPIGatewayRequest(input: com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent, context: com.amazonaws.services.lambda.runtime.Context?): WelcomeMessage {
return WelcomeMessage()
}
}
The decompiled abstract class from the library looks like this:
public abstract class APIGatewayRequestHandler<T> public constructor() : com.amazonaws.services.lambda.runtime.RequestHandler<com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent, T> {
public abstract fun handleAPIGatewayRequest(input: com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent, context: com.amazonaws.services.lambda.runtime.Context?): T
public open fun handleRequest(input: com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent?, context: com.amazonaws.services.lambda.runtime.Context?): T {
/* compiled code */
}
}
I get the following error:
Class 'GetWelcomeMessageHandler' is not abstract and does not implement abstract base class member
public abstract fun handleAPIGatewayRequest(input: APIGatewayProxyRequestEvent, context: Context?): WelcomeMessage

I think you're just missing some override keywords. Namely, your abstract class should have it on the handleRequest method:
public abstract class APIGatewayRequestHandler<T> public constructor() : com.amazonaws.services.lambda.runtime.RequestHandler<com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent, T> {
public abstract fun handleAPIGatewayRequest(input: com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent, context: com.amazonaws.services.lambda.runtime.Context?): T
public override fun handleRequest(input: com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent?, context: com.amazonaws.services.lambda.runtime.Context?): T {
/* compiled code */
}
}
And then your GetWelcomeMessageHandler should have it on its handleAPIGatewayRequest method:
class GetWelcomeMessageHandler : APIGatewayRequestHandler<WelcomeMessage>() { // <-- This curly brace was also missing
override fun handleAPIGatewayRequest(input: com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent, context: com.amazonaws.services.lambda.runtime.Context?): WelcomeMessage {
return WelcomeMessage()
}
}

Related

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
}

Implement interface with suspend function from kotlin in java class

I have kotlin Interface with name MediaBucketProvider. this interface
have 1 suspend functuion that return entity list
interface MediaBucketProvider {
suspend fun getMediaBuckets(bucketType: BucketType): List<MediaBucket>
}
When implementing this interface into kotlin class it worked fine. but when i want to
implement this interface in java class like this
class BucketProviderImpl implements MediaBucketProvider {
#Nullable
#Override
public Object getMediaBuckets(#NotNull BucketType bucketType, #NotNull Continuation<? super List<? extends MediaBucket>> $completion) {
//return buckets
}
}
build failed with below error
BucketProviderImpl.java:14: error: BucketProviderImpl is not abstract and does not override abstract method getMediaBuckets(BucketType,Continuation<? super List<MediaBucket>>) in MediaBucketProvider
class CustomLoaderJavaClass implements MediaBucketProvider {
^
When i remove suspend modifier from interface function build not failed anymore.
I see the kotlin-to-java implementation of Kotlin class that implement MediaBucketProvider interface its not different between BucketProviderImpl and java code of KotlinBucketProviderImpl

Dagger #Provides in Kotlin

I'm trying to understand Dagger. I created applicationInjector class :
class BaseApplication : DaggerApplication() {
override fun applicationInjector(): AndroidInjector<out DaggerApplication>? {
return DaggerAppComponent.builder().application(this)?.build()
}
}
And here's my AppComponent
#Component(
modules = [AndroidSupportInjectionModule::class,
ActivityBuilderModules::class]
)
interface AppComponent : AndroidInjector<BaseApplication> {
#Component.Builder
interface Builder {
#BindsInstance
fun application(application: Application?): Builder?
fun build(): AppComponent?
}
}
Now what I want to do is to to inject simple String to Activity (really basic, right ?)
In Java it works like this :
#Module
abstract class ActivityBuilderModules {
#ContributesAndroidInjector
abstract fun contributeAuthActivity() : AuthActivity
//JAVA
#Provides
public static String provideTestString() {
return "TEST "
}
however we don't have static function in Kotlin, right ? And it needs to be static cause I'm getting an error :
error: com.example.kotlintests.di.ActivityBuilderModules is abstract and has instance #Provides methods. Consider making the methods static or including a non-abstract subclass of the module instead.
public abstract interface AppComponent extends dagger.android.AndroidInjector<com.example.kotlintests.BaseApplication> {
I tried with package level function but it didn't work. How can I add provideTestString function in Kotlin ?

Type mismatch with generic parameter

I'm trying to run the following code, but I'm getting the following compiler error: Error:(12, 9) Type mismatch: inferred type is Child but Parent<Any> was expected.
abstract class Parent<T> {
abstract fun hi()
}
class Child: Parent<String>() {
override fun hi() {
println("Hi from child")
}
}
fun main(args: Array<String>) {
println("Hello, world!")
test(Child())
}
fun test(parent: Parent<Any>) {
parent.hi()
}
But the Java's equivalent, works as expected:
public class HelloWorld {
public static void main(String[] args) {
test(new Child());
}
public static void test(Parent object) {
object.hi();
}
}
abstract class Parent<T> {
public abstract void hi();
}
class Child extends Parent<String> {
public void hi() {
System.out.println("Hi from child");
}
}
What is wrong with the Kotlin code?
You want Parent<String> to be a subtype of Parent<Any>. Since String is a subtype of Any, what you're looking for is called covariance. You can mark the type parameter of Parent to behave this way with the out keyword:
abstract class Parent<out T> {
abstract fun hi()
}
See more about variance in the official documentation.
As for why the Java example works, #Carcigenicate already mentioned in the comment above that you're using raw types there, e.g. the parent parameter of your test function doesn't have a type parameter at all. You can achieve something similar with a star projection in Kotlin, if you really have to:
fun test(parent: Parent<*>) {
parent.hi()
}