简体   繁体   中英

Kotlin constructor properties val can't be used in the class

Following works

class PagerAdapter(var tabCount: Int, fm: FragmentManager?) : FragmentStatePagerAdapter(fm) {
    override fun getItem(p0: Int): Fragment { 
        return when (p0) {
            0 -> TabFragment1()
            1 -> TabFragment2()
            2 -> TabFragment3()
            else -> throw IllegalArgumentException("Invalid color param value")
        }
    }
    override fun getCount() = tabCount
}  

and this doesn't (Unresolved reference :tabCount)

class PagerAdapter(tabCount: Int, fm: FragmentManager?) : FragmentStatePagerAdapter(fm) {
    override fun getItem(p0: Int): Fragment { 
        return when (p0) {
            0 -> TabFragment1()
            1 -> TabFragment2()
            2 -> TabFragment3()
            else -> throw IllegalArgumentException("Invalid color param value")
        }
    }
    override fun getCount() = tabCount
}  

I am new to Kotlin and just confused why can't you use the val properties in the class itself. Can someone please explain? Thanks

The second doesn't work as you are not declaring any properties for the class. Just mentioning them in the brackets does not make them properties, rather it can be compared as if they were just parameters of a constructor.

You either want to use var or val ... you can make them private if you like.

Check also Kotlins reference about classes and inheritance, more specifically the constructor chapter :

In fact, for declaring properties and initializing them from the primary constructor, Kotlin has a concise syntax:

 class Person(val firstName: String, val lastName: String, var age: Int) { ... } 

Much the same way as regular properties, the properties declared in the primary constructor can be mutable var or read-only val .

tabCount and fm in class PagerAdapter(tabCount: Int, fm: FragmentManager?) are just constructor parameters. They are not members of the class.

It is like

class PagerAdapter extends FragmentStatePagerAdapter {
    PagerAdapter(int tabCount, FragmentManager fm) {
        super(fm)
    }
    ...
}

in Java.

You have to specify they are class fields by adding val in front of them.

class PagerAdapter(val tabCount: Int, val fm: FragmentManager?) : FragmentStatePagerAdapter(fm) {
    override fun getItem(p0: Int): Fragment { 
        return when (p0) {
            0 -> TabFragment1()
            1 -> TabFragment2()
            2 -> TabFragment3()
            else -> throw IllegalArgumentException("Invalid color param value")
        }
    }
    override fun getCount() = tabCount
}  

This works

class PagerAdapter(var tabCount: Int) : SomeBase() {
    override fun getCount() = tabCount
}  

since when you specify var or val to primary constructor parameter, the parameter becomes property of the class.


But when you do not specify the parameter with var or val , it is not stored. However, you can still use this value inside init block:

class PagerAdapter(tabCount: Int) {
    init {
        Log.d("$tabCount")
    }
}  

or to initialize some custom property:

class PagerAdapter(tabCount: Int) {
    val tabCountTenTimes: Int = tabCount * 10
}

Though you can't use such a parameter in method like you have tried - you need a property for this.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM