Sergejs Bogdanovs
Sergejs Bogdanovs

Reputation: 19

Kotlin abstract class secondary constructor

I can't create the secondary constructor for this abstract class.

@SuppressLint("StaticFieldLeak")
abstract class BaseAndroidViewModel(
        application: Application,
        private val creditsGetByIdUseCase: CreditsGetByIdUseCase,
        private val videosGetByIdUseCase: VideosGetByIdUseCase,
        private val reviewGetByIdUseCase: ReviewGetByIdUseCase,
        private val addToFavoritesUseCase: AddToFavoritesUseCase,
        private val getFavoriteByIdUseCase: GetFavoriteByIdUseCase
) : AndroidViewModel(application) {

constructor(application: Application) : this(application) // There's a cycle in the delegation calls chain error

Upvotes: 2

Views: 4130

Answers (3)

Alok Mishra
Alok Mishra

Reputation: 2034

You can call secondary constructor like this -

@SuppressLint("StaticFieldLeak") abstract class BaseAndroidViewModel : AndroidViewModel{
constructor(application: Application,
            creditsGetByIdUseCase: CreditsGetByIdUseCase,
            videosGetByIdUseCase: VideosGetByIdUseCase,
            reviewGetByIdUseCase: ReviewGetByIdUseCase,
            addToFavoritesUseCase: AddToFavoritesUseCase,
            getFavoriteByIdUseCase: GetFavoriteByIdUseCase) : super(application)

constructor(application: Application) : super(application) }

Upvotes: 9

crgarridos
crgarridos

Reputation: 9283

The reason you are getting a cycle in the delegation calls chain error, is because

constructor(application: Application): this(application)

Is the equivalent to java:

public MyClass(Application application){
    this(application)
}

This said you are calling your constructor recursively.


As stated in Alok Mishra's answer, you should instead make a call to the super constructor.

constructor(application: Application): super(application)

That is actually the equivalent of your primary constructor:

BaseAndroidViewModel(application: Application): AndroidViewModel(application)

You can constate that this is just a replacement of keywords constructor by BaseAndroidViewModel and super by AndroidViewModel

Upvotes: 0

Sergio
Sergio

Reputation: 30755

When you create a secondary constructor, and a class has non empty primary constructor, you should pass all parameters that primary constructor has, e.g.:

abstract class BaseAndroidViewModel(
        application: Application,
        private val creditsGetByIdUseCase: String,
        private val videosGetByIdUseCase: String
) : AndroidViewModel(application) {

    constructor(application: Application) : this(application, 
            "creditsGetByIdUseCase", "videosGetByIdUseCase") // here we pass other necessary parameters
}

In your case it might be the following:

@SuppressLint("StaticFieldLeak")
abstract class BaseAndroidViewModel(
    application: Application,
    private val creditsGetByIdUseCase: CreditsGetByIdUseCase?,
    private val videosGetByIdUseCase: VideosGetByIdUseCase?,
    private val reviewGetByIdUseCase: ReviewGetByIdUseCase?,
    private val addToFavoritesUseCase: AddToFavoritesUseCase?,
    private val getFavoriteByIdUseCase: GetFavoriteByIdUseCase?
) : AndroidViewModel(application) {

    constructor(application: Application) : this(application, null, null, null, null, null)
}

Or you can create primary constructor with default parameters:

abstract class BaseAndroidViewModel(
        application: Application,
        private val creditsGetByIdUseCase: CreditsGetByIdUseCase? = null,
        private val videosGetByIdUseCase: VideosGetByIdUseCase? = null,
        private val reviewGetByIdUseCase: ReviewGetByIdUseCase? = null ,
        private val addToFavoritesUseCase: AddToFavoritesUseCase? = null,
        private val getFavoriteByIdUseCase: GetFavoriteByIdUseCase? = null
    ) : AndroidViewModel(application) { ... }

Upvotes: 3

Related Questions