Protected functions in interfaces


#1

I’m trying to understand why functions in interfaces can’t be protected. I can’t really see what problems would be presented by having protected functions that aren’t already present from having both public functions with default implementation and private functions. I’ve run into many situations where a protected helper function in an interface, that isn’t exposed to users of an implementing object, would be helpful for reducing code replication. One example is a variable property with a protected set but with no backing field of course.

Am I missing something or is the use of protected in interfaces a possibility in the future?

edit: come to think of it even the ability to have a private set on a var would be nice. So a property that has a read only interface everywhere outside of the interface it is declared in. Here is an example of where it’s useful:

interface Module {
    var owner: Owner
       private set

    fun notifyReconfiguration() {
        if (aOwner.contains(this))
            owner = aOwner
    }
}

#2

See https://blog.jetbrains.com/kotlin/2015/09/feedback-request-limitations-on-data-classes/#comment-38249

Also see comments in https://youtrack.jetbrains.com/issue/KT-3029

I feel your pain. This was also disappointing to me …


#3

Oh, I didn’t realize it was a JVM issue, I guess it made some sense before Java 8 but it doesn’t really anymore. Hopefully this changes eventually. My example of a public var with a private set should still be possible though, any idea why that isn’t allowed?


#4

You declare private set without implementation and expect it to be provided by the implementer, don’t you? Private doesn’t work that way: by definition it is visible only from the same scope it is declared in.

An interface in Kotlin can have private functions and properties, but they must have an implementation, and they can be called only from other members of that interface.


#5

Yeah, I should have implemented get and set in my example but it doesn’t work with an implementation of get and set for the property either.

var otherThing = ""

interface ThingAdjuster {
    var thing: String
    get() = otherThing
    private set(value) {
        otherThing = value
    }

    fun doSomething(i: Int){
        if (i - 5 < 0)
            otherThing = "less"
        else
            otherThing = "more"
    }
}

This is the same as:

var otherThing = ""

interface ThingAdjuster {
    fun getThing() = otherThing
    private fun setThing(value: String){
        otherThing = value
    }

    fun doSomething(i: Int){
        if (i - 5 < 0)
            setThing("less")
        else
            setThing("more")
    }
}

Obviously my example isn’t very useful, I’m not sure how useful this would be in general. It doesn’t seem as though anything is accomplished by forbidding it though. I was just trying to think of anything I could eek out since protected properties aren’t allowed.