Classifier does not have a companion object, and thus must be initialized here
Solution 1
This line selection=RowSubTShirtViewModel
references the view model as if it were a named object, meaning you would have written instead of class object:
object RowSubTShirtViewModel {
//...
}
However, since that's not the case, kotlin is telling you that you cannot reference it like that and must initialize it. The constructor as quite a lot of parameters for me to guess what they are, but essentially you'd have to pass them in:
selection=RowSubTShirtViewModel(/*parameters here*/)
Solution 2
Having a companion object (and having members in that companion object) in Kotlin is equivalent to having static members (static methods or fields) in Java, and as it is known, static members in Java can be accessed without initializing the class or having a reference to an object of that class. For example, given:
// this is Java
class A {
static void s() {System.out.println("static");}
void d() {System.out.println("dynamic");}
}
we could call the s()
method without initializing the class A
, like this: A.s();
, and it would print "static", but in order to be able to call the d()
method, we need an object of the A
class, which we can get by either initializing it elsewhere like this: A a = A();
, and then doing a.d();
or doing them together like this: A().d();
, both of which would print "dynamic".
Even though Kotlin does not have the static
keyword, it must have the same functionality since any Java code can be translated into Kotlin code. Now when we want to transfer this train of thought into Kotlin, we would instead say something like "in order to use members from the companion object (static members, basically), you must initialize the class name (i.e. create an object)".
So when Kotlin complains and says Classifier Something
does not have a companion object, and thus must be initialized here, it is basically telling you that that class does not have any static members (since it does not have a companion object), and so if you want to use it, either use it with parenthesis (initialize it to create an object of it), or declare a companion object in it (using the companion object
keyword).
I hope this clears things up. Sadly, uninformative messages like this prove that you need prior Java understanding to learn Kotlin, a fact that haunts it and will hinder its ability to stand alone as a language.
Farhana Naaz Ansari
Farhana... The only way of writing fewer bugs is writing less code.
Updated on April 22, 2022Comments
-
Farhana Naaz Ansari about 2 years
I have an Activity where an interface is declared and I have a
ViewModel
class which has overridden interface and want to invoke the method of interface fromActivity
to make changes inViewModel
class but unable to call method inActivity
saying ViewModel class does not have a companion object, and thus must be initialized here. How to resolve this?var selection: setSelectionSubRow? = null selection=RowSubTShirtViewModel selection!!.setNameSelection(false)
above code is in
Activity
whose name isTShirtActivity
.below code is from
RowViewModel
classclass RowSubTShirtViewModel(private val subTShirtAdapter: SubTShirtAdapter, val context: TShirtActivity, val tShirtBean: CommonItemBean, private val parentPosition: Int, private val position: Int) : BaseObservable() ,TShirtActivity.setSelectionSubRow{ fun getImageDrawable(): Drawable { return if (tShirtBean.isSelected) ContextCompat.getDrawable(context, R.drawable.green_border_circle)!! else ContextCompat.getDrawable(context, R.drawable.border_circle)!! } override fun setNameSelection(selection: Boolean) { if (parentPosition == 6) { if (position == 1) { tShirtBean.isSelected = false } } }
-
Farhana Naaz Ansari over 5 yearsI got your point. but other problems have to face, Actually this
RowSubTShirtViewModel
is aviewmodel
ofsubAdapter
class and it is using inViewModel
class ofActivity
and there is adialog
inactivity
, indialog
on button click I want to reverse selection ofRecycleView
item and theRowSubTShirtViewModel
is aviewModel
for the adpater of thatrecyclerview
, so how can i manage constructor ofRowSubTShirtViewModel
inAcitivty
-
Fred over 5 yearsThat's just a classic dependency problem. You just carry on passing everything until you have all you need. For example, if you construct
RowSubTShirtViewModel
in the adapter, which is used in an activity, then you can pass the activity as you instantiate the adapter and then pass it in as you instantiateRowSubTShirtViewModel
. There are other approaches using dependency injection frameworks like Dagger. I can't really tell you what suits you best, but the problem you're having will always lead to having to buildRowSubTShirtViewModel
. -
Farhana Naaz Ansari over 5 yearsThanks Fred I will look both the solutions.