How would you solve this in Kotlin?


#1

I'd like to create an extension value on a Java class and call a protected function in the Java class. I realize this isn't allowed because only public methods can be called from an extension function.

Example:

var A.doit : String
  get() = {
          return getDoit()   // getDoit is protected in A
  }
  set(value) = {
          setDoit(value)
  }

I tried making a wrapper class using a delegate that would create a new public method that accesses the protected method:

class MyA(delegate: A) : A by a {
  public getDoit2() {
          return getDoit();
  }
}

However, delegates don’t work with Java classes. The obvious solution is to duplicate the Java hierarchy in Kotlin instead of using extension functions but that’s a whole world of pain with a huge hierarchy.

I like to eventually call a.doit or a.doit = “hello” instead of A.setDoit(“hello”)

Just wondering if there’s an obvious solution I’m missing, being new to Kotlin…

Curtis


#2

Did you try just extending from A and overriding the method to make getDoit() public?

Incidentally how do you mean delegation doesn’t work for Java classes? (Just wondered; haven’t used it much yet - do you mean it only works for interfaces?)


#3

> only public methods (not protected) can be called from an extension function That's right.

> However, delegates don’t work with Java classes.
Yes, it works only with Kotlin traits and Java interfaces.

> I like to eventually call a.doit or a.doit = “hello” instead of A.setDoit(“hello”)
It’ll be done automatically for Java getters and settters, but this functionality isn’t implemented yet.


#4

Yes, that's one way to go but then I'd have to replicate the entire hierarchy in Kotlin, which I'm trying to avoid.

You can’t delegate to any Java class or interface. In my example, trying to delegate to String doesn’t work because it’s a Java class.

I’m sure you saw Svetlana’s message about only being able to delegate to Kotlin traits.

I’m looking forward to the automatic getters and setters on Java classes that she mentioned.


#5

So you're saying you've a huge hierarchy of classes and they all have a protected getter method you want to expose? If deriving from the classes to fix the code isn't an option, I'd try fix/patch the library - or use reflection in an extension method.

Am not sure of a cleaner way around your issue - in any statically typed JVM programming language.


#6

Yes, I'm actually trying to make a Kotlin API for JavaFX. It has a large hierarchy of shapes, controls, etc. Only the "Parent" class so far has a protected item I need access to but once I subclass that one, I'll need to create Kotlin subclasses of the rest of the hierarchy involved with that one class.

One good thing about sticking with extensions is that I can deal with the existing Java classes and not have to subclass and duplicate all of the functionality that already exists.

Of course, I could be missing something :slight_smile:


#7

Wow, just two days ago I thought about the same: make JavaFX wrapper to make UI...