1

This is the first time I ask a question, please excuse my mistake on asking a question, and tell me how to ask a better question if that happens.

What I am asking:

How can I add a member function, into an anonymous object, which is callable outside this object? Or this requirement is too strange that shouldn't be implemented?

Consider this object expression below:

variable = object : AClass()
{
    // inside the declaration of anonymous object

    override fun aFunction(i: Int)
    {
        // do something inside aFunction
    }
}.apply {
    // do something inside apply
}

How can I add a function fun bFunction(i: Int), that just belongs to variable, not belongs to AClass, that can be callable by directly using

variable.bFunction(1)

? Or, it is impossible to do so?

What I have tried (and, of course, not satisfy what I want):

  • I can create an extension function fun AClass.bFunction(i: Int) to solve it, however this maybe "unfair" to other instance of AClass, since they actually don't need that.
  • I can create a class instead of using an anonymous object locally, however it seems too heavy to create a class for ONE variable.
  • I have tried adding bFunction inside the declaration of anonymous object, where the position is mentioned above. However I can just only access this function inside .apply {}, not outside this assignment.
  • I have tried adding bFunction inside .apply {}, however it also make me just access it inside .apply {}, not outside this assignment.

To be more specific of the original question (which is solved by myself, while typing this question) to avoid an X - Y question:

I am struggling on painting on Java GUI components. What I want to achieve is like a "canvas" or a "paper" inside a JFrame, where I can paint anything I like on it, by pixel control, totally using Kotlin.

After some searching, I found that the core solution to the question of, "if I draw something by using contentPane.graphics.drawXXX series function, this draw will be disappear when (I resize or minimize this JFrame, or just called this draw function too early, when this JFrame is showing (note: we can use Thread.sleep to delay too-early call))", is by overriding paint function. Then, in order to override it, I use var image = BufferedImage(...) to store what I have painted, and use an anonymous object

painting = object : JFrame()
{
    override fun paint(g: Graphics?)
    {
        contentPane.graphics.drawImage(image, 0, 0, this)
    }
}.apply { /* do some initialization */ }

to override paint function, and draw this buffered image into contentPane, which seems achieved what I want, and just a "static" painting.

I was wondering how can I add a updatePainting() function to this painting, which make me can just modify this buffered image, then call this function to update the painting, as a "dynamic" painting. However, during the time I am typing this question, I accidentally find that, just modify this image, will automatically update this painting, no need to manually update this painting. So this original question actually solved: this bFunction is not necessary in my current situation. But, I just wondering, are there any way to implement this things that can fit this (may be strange) issue?

Geno Chen
  • 3,835
  • 6
  • 16
  • 32

1 Answers1

1

Actually, this code (with bFunction inside the declaration of anonymous object) will work perfectly well and will make bFunction accessible outside... but only if variable is local or private. In both cases it has to be initialized like this together with declaration, i.e. val variable = object : AClass() ....

Public/protected properties need a type which can be used outside the class which declares them, unsurprisingly. In that case you'll have to name the subclass.

The page you link covers this

Note that anonymous objects can be used as types only in local and private declarations. If you use an anonymous object as a return type of a public function or the type of a public property, the actual type of that function or property will be the declared supertype of the anonymous object, or Any if you didn't declare any supertype. Members added in the anonymous object will not be accessible.

Alexey Romanov
  • 154,018
  • 31
  • 276
  • 433
  • Thank you! The most important part is **it has to be initialized like this together with declaration**, to avoid explicit type declaration of `variable`, to avoid the "type narrowing" of `variable`, which will make `variable` lost that `bFunction`. – Geno Chen Jul 04 '18 at 17:35
  • Yes, that's exactly the reason. – Alexey Romanov Jul 04 '18 at 18:01