Interface method in Kotlin should support protected && internal visibility modifier


#1

As interface in Kotlin can implement method as default, we can not just treat interface as traditional interface which means ‘what you can see from outside the class’. It really like a superclass we can extend from it, and in the interface we select which method to exposed to outside.

Let’s make a sample. I want to expand all my custom view with update data function.As my custom view may extend from different base-view(LinearLayout, FrameLayout, ScrollView, View…),i can not do this thing in the superclass. The best way is implementing an interface like IViewDataUpdater.

interface IViewDataUpdater{
	fun updateData(data: Data){
		if(data.isValid){
			updateDataValid(data)
		} else {
			updateDataInvalid(data)
		}
	}
	
	fun updateDataValid(data: Data)
	
	fun updateDataInvalid(data: Data)
}

But in this sentence, i really don’t want to expose my updateDataValid and updateDataInvalid to outside, updateData is the only method i really expose. So code as below is what i want.

interface IViewDataUpdater{
	fun updateData(data: Data){
		...
	}
	
	protected fun updateDataValid(data: Data)
	
	protected fun updateDataInvalid(data: Data)
}

Maybe the example is not the best scenarios of use, it exactly explain the problem.


Interface internal members support: suggestion
#2

+1


#3

@ohmerhe nice question.+1


#4

In this case you need a helper class with update data logic, interface default method isn’t a work around for multi inheritance and non-public method in Java interface sounds hard.


#5

I know what do you mean, and i do what you say before i use Kotlin.

But i think interface provide default implement for method can bring new develop pattern, and it’s more convenient to expand class capacity and easy to maintenance. Why do not try new pattern?


#6

Primary for JVM compatibility problems.


#7

Generally speaking, “why do not try new pattern?” is not how language design works. Adding a new feature to a language takes a lot of time and resources, so every new feature requires a very strong argument showing what problems it can solve, and why existing solutions for those problems are not adequate. So far I don’t see any convincing argument.

(Note that Java does not support non-public methods in interfaces, so we would need to come up with some kind of special encoding for such methods, which would make Java interoperability more difficult.)


#8

If i can do it, different function modules can be split clearly and i don’t need class like Helper which often need to create relations or bind with it. It also make grouping different modules easily and looks more intuitive.

Of course designing language is hard and complicated, and new feature may cost time and resources, and to any new feature you should be careful. But as a user of Kotlin, i advice my idea from my firsthand experience. if the advice do not break some rules and can bring convenience to coder, i think we can discuss with it.

In consideration of compatibility with java or other things, maybe it’s difficult, you can accept my advice or not, it is just advice. And as i know internal visibility modifier is not supported by Java too.


#9

+1 to this feature.

It is very strange that interfaces can’t have protected methods due to JVM interoperability issues, but do can have private methods.

How are private methods implemented?


#10

For the jdk 6 target private methods are implemented the same way that public methods are. As static methods of an inner class. If your class inherits this, it will generate implementations (if it’s not overridden) for all the “implemented” methods by making them call the static method with the object as the first parameter. Private methods are only accessible inside the inner class so don’t need overriding. Java interfaces at 7 or below don’t allow non-public members (they would not make sense as the only point of implementing a method is to call it and and interface itself can’t do that).
Basically the JVM was designed very closely to Java, as such non-java allowed features are generally forbidden (strangely enough you can use names with characters that are forbidden in java-the-language). JVM Spec 7 specifies that fields must be public static final and methods must be public and abstract and may only have vararg, bridge and synthetic as other attributes.
When targeting JVM 6 or 7 this basically restricts what is possible. Of course it is possible to have compilation-only restrictions such as Kotlin’s internal (which basically just renames the method and adds some attributes in the class file - a jvm must silently ignore attributes not understood). In JVM spec 8 protected visibility is still not allowed.