lampenlampen
lampenlampen

Reputation: 947

Kotlin Object Supertype Constructor

I need to implement a singleton MyClass in kotlin.

Requirements:

  1. MyClass has the supertype SuperClass and I need to call the constructor of Superclass
  2. I need to pass a context to MyClass and need the context to call the constructor of Superclass.
  3. MyClass is a singleton.

Java equivalent:

class MyClass extends SuperClass
{
    // instance variable
    // getInstance() method
    MyClass(Context context)
    {
        super(context);
    }
}

I tried to solve this with an object but didn't get it working.

Is there a way to get it working with an object or do I have to use a companion object?

Upvotes: 1

Views: 5223

Answers (2)

Eugen Pechanec
Eugen Pechanec

Reputation: 38223

Consider the following super class:

open class MySuperClass(val context: Context) {...}

Since Kotlin objects only have an empty constructor, you'd need a structure similar to the following:

// Private constructor is only accessible within the class.
class MySingleton private constructor(context: Context) : MySuperClass(context) {
    companion object {
        lateinit var INSTANCE: MySingleton
            // Instance setter is only accessible from within the class.
            private set

        // Custom init function is called from outside and replaces
        // THE WHOLE SINGLETON with a new instance
        // to avoid internal dependencies on the old context.
        fun init(context: Context) {
            INSTANCE = MySingleton(context.applicationContext)
        }
    }

    // Lazily initialized field dependent on a Context instance.
    val prefs by lazy { PreferenceManager.getDefaultSharedPreferences(context) }
}

You need to call init(context) once before using your singleton class and the Application is a great place to do that. This will also create a new instance of your singleton each time Instant Run loads a new Application object so you always end up with the most up-to-date application context.

class MyApplication : Application() {
    override fun onCreate() {
        super.onCreate()

        // Eagerly initialized singleton.
        MySingleton.init(this)
    }
}

Notes:

  • Kotlin objects only have an empty constructor. If you need to initialize the object use a custom init function.
  • If your fields depend on a context which may change it's better to use class instead of object and manage current instance yourself. You also have to do this if you need to pass parameters to super class of your singleton.
  • Because you eagerly initialize the class at the start of your application (not at the first call of getInstance(context) it's a great idea to lazily the heavy objects within your singleton object.
  • If your app is multi-process find a way to initialize your singleton only in the process you actually use it. (Hint: ContentProvider is created only in main process by default.)

Upvotes: 2

marstran
marstran

Reputation: 27971

You don't need any objects or companion objects to achieve this. This is the syntax for calling the constructor of a superclass in Kotlin:

class MyClass(context: Context) : SuperClass(context)

Upvotes: 0

Related Questions