Implement interfaces as private/protected


#1

Hey,

I’m wondering, since I use Coroutines, if there is a way to implement an interface with private or protected (if i remember correctly this is possible in C#), but unfortunately it isn’t. Why is that desirable?

Sometimes I want an Interface to act as a tool to define scope (e.g. for extension functions). Let’s say I want to use a coroutine in a class I usually implement the CoroutineScope interface to define the scope of my coroutine. But this is also effectively making my coroutine accessible from the outside, which is usually absolutely NOT what I want. I think is would be absolutely meaningful to be able to have a private or protected modifier to constrain the usage of the coroutine, e.g.:

class Foo : protected CoroutineScope { ... }

To work around that of course I can implement a local, protected instance of CoroutineScope and use e.g. with(scope) { launch... } or scope.launch... to access the scope.

protected val coroutineScope = createCoroutineScope() // some factory function

init {
    with (coroutineScope) {
        launch { ... }
    }
}

fun doSomething = coroutineScope.launch { ... }

But that’s not always desirable and not at all convenient in my opinion. Additionally, what if you have multiple scopes you want to use? There is nothing like with(coroutineScope, someOtherScope) (yet)… (of course you can define an interface interface CombinedScope : CoroutineScope, SomeOtherScope) but I don’t know if that’s really the best way).

What do you think about that requirement? Is it necessary? Please let me know if you think differently or know a better way to work around the problem. Thank you!


#2

Foo is CoroutineScope?

What do you think about that requirement? Is it necessary?

No, we are considering a different solution


#3

Yes, Foo is the scope in which I want to use a coroutine.

You are not very specific in what your solution is. What is it actually?


#4

Ok, so if Foo is CoroutineScope then Foo as CoroutineScope is a good statement, so interface is no more protected.

But this is also effectively making my coroutine accessible from the outside, which is usually absolutely NOT what I want.

I fully agree with you and I already exposed my point of view for your specific issue (https://github.com/Kotlin/kotlinx.coroutines/issues/410#issuecomment-403315557).

Regarding your proposal (as you explained it), I cannot see a good implementation that work with type inference, casting and reflection, sorry.

You called it in your first message “work around”.


#5

OK thanks for the clarification. I find it not optimal that way, as having the scope tied to the class using the scope would make things much more easy. Actually also many people suggest doing so e.g. for Android activities (which I consider problematic, as we all agree). But honestly, it’s also quite convenient. It would be really nice to define scope for extensions that way.