Search code examples
androidkotlinandroid-roomabstract-classabstract

Instance of abstract class in Kotlin and calling abstract function without overriding


I am doing this google codelab android-room-with-a-view-kotlin. This is the link to codelab. At the 8th step when creating room database they have used this code

// Annotates class to be a Room Database with a table (entity) of the Word class
@Database(entities = arrayOf(Word::class), version = 1, exportSchema = false)
public abstract class WordRoomDatabase : RoomDatabase() {

   abstract fun wordDao(): WordDao

   companion object {
        // Singleton prevents multiple instances of database opening at the
        // same time. 
        @Volatile
        private var INSTANCE: WordRoomDatabase? = null

        fun getDatabase(context: Context): WordRoomDatabase {
            // if the INSTANCE is not null, then return it,
            // if it is, then create the database
            return INSTANCE ?: synchronized(this) {
                val instance = Room.databaseBuilder(
                        context.applicationContext,
                        WordRoomDatabase::class.java, 
                        "word_database"
                    ).build()
                INSTANCE = instance
                // return instance
                instance
            }
        }
   }
}

I want to ask why there is no error in these 2 lines (val exam & val dao) where I create an instance of this abstract class (in class A) and then call its abstract function(getNoteDao) without overriding it.

class A{

val exam : WordRoomDatabase = WordRoomDatabase.getDatabase(application) 
val dao = exam.getWordDao()
}

Since we know we need to override the abstract function and can not directly call it but what's happening there. why is there no error


Solution

  • There's no error on the exam line because getDataBase is a "companion" object, or if you're from the Java world, it means it's a "static" function within the abstract class. This means

    • a function within a companion object (or again, a static function) belongs the the CLASS, not the the INSTANCE of the class
    • you CAN NOT call a static/companion object function on the instance of the class, so notice when you call "WordRoomDatabase.getDatabase..." there are no parenthesis at the end of "WordRoomDatabase". You didn't need to create an instance of it in order to call the getDatabase function

    There is no error in line 2 is a little trickier to spot. Inside of getDatabase() you are Room.dataBaseBuilder(...) and passing in the abstract class. Inside of that builder, android actually creates the instance of your abstract WordRoomDatabase. class and overrides your abstract wordDao function

    If you're using AndroidStudio, build your code. After it's done there will be a little green arrow pointing down on the column next to WordRoomDatabase. If you click on it, you'll be able to see the class that Room generated that overrides your abstract function