0

It's hard to explain but I basically want to be able to have an interface which my subclasses need to implement, which mandates a static constant. How would I achieve this in Kotlin?

I have the following class/interface:

interface BaseFragmentInterface {
  val TAG: String
}

class BaseFragment: Fragment() {
  /* this, of course, doesn't compile right now: */
  companion object: BaseFragmentInterface {}

  func<T: BaseFragment> push(fragment: T) {
    /* Here I want to access TAG */
    Log.d(T.TAG, "Push Fragment")
  }
}

My subclasses need to be required to implement the interface. And my base companion object would need to be somehow abstract.

Any idea how to achieve this?

Leandros
  • 16,805
  • 9
  • 69
  • 108
  • 1
    So I guess that your `BaseFragment` should be `abstract` right? Since in the code snippet you provided, it's `final`. – Giorgio Antonioli Apr 07 '20 at 10:30
  • I think it is the same question as here: https://stackoverflow.com/questions/35327443/companion-objects-in-kotlin-interfaces – Neo Apr 07 '20 at 10:48
  • @Neo I have found this before. It doesn't work, unfortunately. There is no base class for this to access it the way I need it. – Leandros Apr 07 '20 at 11:08

1 Answers1

3

Let me precise few things.

My subclasses need to be required to implement the interface.

There's no way to achieve this, you can't force a subclass' companion object to implement your interface since the companion object of a class is not related to the companion object of its superclass.

And my base companion object would need to be somehow abstract.

Since the companion object is an object, it can't be abstract, because an object can't be abstract too.

Said that, you have two options to still achieve your desired behavior:

  1. Use TAG as a non-static final property inside BaseFragment:
abstract class BaseFragment : Fragment() {
    protected abstract val TAG: String

    fun <T : BaseFragment> push(fragment: T) {
        /* Here I want to access TAG */
        Log.d(TAG, "Push Fragment")
    }
}

class FragmentImpl : BaseFragment() {
    override val TAG: String = "fragment-impl"
}
  1. Use companion objects to hold the tag, make the type T of push() as reified and access the TAG property inside the companion object of T using the reflection.
Giorgio Antonioli
  • 15,771
  • 10
  • 45
  • 70