Why interface cant be used in kotlin inner class? - kotlin

class SelectionRAdapter(var list: ArrayList<Image>) :
RecyclerView.Adapter<SelectionRAdapter.FolderRViewHolder>() {
inner class FolderRViewHolder(var view: View) :
RecyclerView.ViewHolder(view), View.OnClickListener {
init {
view.setOnClickListener(this)
}
override fun onClick(v: View?) {
view.checkbox_container.setBackgroundColor(Color.parseColor("59FFFFFF"))
}
interface OnItemSelectListener {
}
}
}
when I try add interface to kotlin inner class it shows interface not allowed here exception may i know the reason behind it? when i trying communicate with inner class with parent class using interface

Related

Kotlin concrete class extending from abstract class and interface, with the interface using a method implemented in the abstract class

I want to ask a question that I have some clues about, but I don't want to influence the answers I will get. I have the following class hierarchy:
abstract class MyAbstractClass {
fun displayStuff(id: String) {
println("My id is $id.")
}
}
interface MyInterface {
fun displayThis() {
displayStuff("some-value")
}
fun displayStuff(id: String) // Not implemented here
}
class MyConcreteClass(): MyAbstractClass(), MyInterface {
fun doStuff() {
displayThis()
}
}
fun main() {
val result = MyConcreteClass()
result.doStuff()
result.displayStuff("id")
}
What's wrong with this design, and how do you suggest I fix it?
It would probably not be a bad idea to extract the displayStuff into another interface. Then MyAbstractClass and MyInterface can both derive from the same interface.
One overrides the displayStuff function, hence providing something like an abstract base implementation for the interface.
The other one is using the function in a specific way, thereby extending the functionality of the interface.
interface DisplayStuff {
fun displayStuff(id: String)
}
abstract class MyAbstractClass: DisplayStuff {
override fun displayStuff(id: String) = println("My id is $id.")
}
interface MyInterface : DisplayStuff {
fun displayThis() = displayStuff("some-value")
}

Dagger #Provides in Kotlin

I'm trying to understand Dagger. I created applicationInjector class :
class BaseApplication : DaggerApplication() {
override fun applicationInjector(): AndroidInjector<out DaggerApplication>? {
return DaggerAppComponent.builder().application(this)?.build()
}
}
And here's my AppComponent
#Component(
modules = [AndroidSupportInjectionModule::class,
ActivityBuilderModules::class]
)
interface AppComponent : AndroidInjector<BaseApplication> {
#Component.Builder
interface Builder {
#BindsInstance
fun application(application: Application?): Builder?
fun build(): AppComponent?
}
}
Now what I want to do is to to inject simple String to Activity (really basic, right ?)
In Java it works like this :
#Module
abstract class ActivityBuilderModules {
#ContributesAndroidInjector
abstract fun contributeAuthActivity() : AuthActivity
//JAVA
#Provides
public static String provideTestString() {
return "TEST "
}
however we don't have static function in Kotlin, right ? And it needs to be static cause I'm getting an error :
error: com.example.kotlintests.di.ActivityBuilderModules is abstract and has instance #Provides methods. Consider making the methods static or including a non-abstract subclass of the module instead.
public abstract interface AppComponent extends dagger.android.AndroidInjector<com.example.kotlintests.BaseApplication> {
I tried with package level function but it didn't work. How can I add provideTestString function in Kotlin ?

Access methods as subclass

Let's say I created a class which extends from another class and I want to override one of the parent functions but I want this function to be private from outside (like protected in Java).
I tried to use protected as it says here but it doesn't work.
Is it possible with Kotlin?
open class YesNoDialog(context: Context, styleRes: Int) : Dialog(context, styleRes) {
protected fun setTexts() {
}
}
class MultiSelectDialog(context: Context, styleRes: Int):YesNoDialog(context, styleRes) {
}
In this example I want to access setTexts from MultiSelectDialog class
It can be done with protected, but you also need to add open to allow it to be overridden:
open class YesNoDialog(context: Context, styleRes: Int) : Dialog(context, styleRes) {
protected open fun setTexts() {
}
}
class MultiSelectDialog(context: Context, styleRes: Int) : YesNoDialog(context, styleRes) {
override fun setTexts() {
}
}

Class subclass type with a public method

I don't understand why in Subclass definition a public method is involved
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView)
Source code of the RecyclerView.ViewHolder
public abstract static class ViewHolder {
public ViewHolder(View itemView) {
if (itemView == null) {
throw new IllegalArgumentException("itemView may not be null");
}
this.itemView = itemView;
}
Your question is why does the following code appear to call a public method ViewHolder within RecylcerView. Here is your code, with a slight rename to make things clearer:
class MyClass(itemView: View) : RecyclerView.ViewHolder(itemView)
And what is missing from your description is showing the outer class:
class RecyclerView { // outer/containing class
static class ViewHolder { // nested class
public ViewHolder(ViewItem view) { // constructor
// ... constructor body
}
}
}
Now looking at that nesting, to talk about the ViewHolder class you need to reference it as RecyclerView.ViewHolder. Then if you want to construct an instance of that you must add the constructor parameters, for example in Java:
new RecyclerView.ViewHolder(view);
In Kotin when you descend from a class, your constructor must call the super constructor and the short hand for that is to do it in the declaration.
class MyClass(ViewItem view) : RecyclerView.ViewHolder(view) {
// ...class body
}
This says MyClass descends from ViewHolder which is a nested class of RecyclerView and the constructor parameter coming into MyClass constructor is being passed into the super constructor of ViewHolder.
This is the same as Java:
class MyClass extends RecyclerView.ViewHolder {
public MyClass(ViewItem view) {
super(view);
}
}
You can also import the nested static class directly, then drop the RecyclerView prefix, but it is a bit clearer to leave it.

override function with concrete type parameter

Hi I would like know why the following example doesn't work
abstract class BaseClass {
}
class ConcretClasOne : BaseCalculator {
}
class ConcretClasTwo : BaseCalculator {
}
abstract class BaseRun {
abstract fun run(param: BaseClass): Int
}
class ConcretRun : BaseRun {
override fun run(param: ConcretClasOne): Int {
return 0
}
}
this shows me a message run overrides nothing.
I suppose that kotlin isn't able to match the abstract class and the concrete implementation, but what other alternative is there to emulate this behavior, that the run method in the concrete class ConcretRun should receive a concrete param ConcretClasOne?
Generics
Using generics, you can make the base class have a type extending the base class, so that the run method can take that type in.
abstract class BaseClass {
}
class ConcretClasOne: BaseCalculator {
}
class ConcretClasTwo: BaseCalculator {
}
abstract class BaseRun<T: BaseClass> {
abstract fun run(param: T): Int
}
class ConcretRun: BaseRun<ConcretClasOne> {
override fun run(param: ConcretClasOne): Int {
return 0
}
}
Why your code doesn't work
At the moment you are trying to override a method with a more specific type, but as the more general base method can accept more types the more specific method cannot override it.