21

I am very new to Kotlin.

I want to be able to add a function to my abstract class, so when I define that function I will be able to invoke that on every child from that class(they inherit the abstract class)

However,I want to define those extension functions in other file. I can't access those functions when i try to invoke them on a particular child implementation of the abstract class.

What are the rules, that I need to made to resolve my problem?

I want to by able achieve something like this:

abstract class Parent(val val1, val val2, val val3){}

class Child(var val1, var val2, var val3) : Parent(val1, val2, val3){}

class Child2(var val1, var val2, var val3) : Parent(val1, val2, val3){}

The extension method for parent and all childs:

 fun Parent.convertToChild2( ): Child2? {

return //some creation method of Child2
} 

And I want to be able to invoke this:

child: Child
child.convertToChild2

I defined all classes in separate file and also the extension function in other file.

I cannot access the function like this - is not visible.

Aditi Parikh
  • 1,522
  • 3
  • 13
  • 34
K.Os
  • 5,123
  • 8
  • 40
  • 95

4 Answers4

25

The answer for my question, that satisfies me is just to extract the method to some "object" structure in other file and whenever we want to access that function we must import the path(package.object.method) to this.

But the problem is, that IDE is not propose me the path to my extension function - i must import it by myself.

I am using Android Studio 3 preview, hope this will be fixed.

UPDATE

It is better to define those function in just plain Kotlin file, so the functions will be not owned by any structure. Then it will be not a problem with importing those automatically by IDE from any place.

Adam Johns
  • 35,397
  • 25
  • 123
  • 176
K.Os
  • 5,123
  • 8
  • 40
  • 95
3

I believe that there is a misunderstanding here about extension functions. Extension functions are regular static functions that take in an instance of the receiver class as a parameter implicitly when you define the function and operate on it.

These static functions (aka extension functions) have some limitations.

They are not added to the class hierarchy so subclasses can not inherit them (if you define extension function for parent class you can't expect that method to be present in child class)

They don't have access to the private properties of the class that they are extending.

Also, they are resolved statically, for example (taken from here)

open class Shape

class Rectangle: Shape()

fun Shape.getName() = "Shape"

fun Rectangle.getName() = "Rectangle"

fun printClassName(s: Shape) {
  println(s.getName())
}     

printClassName(Rectangle())

This example prints "Shape", because the extension function being called depends only on the declared type of the parameter s, which is the Shape class.

Mr.Q
  • 4,316
  • 3
  • 43
  • 40
2

First of all: There a many errors in your source code, you should fix before asking the question here (missing type annotations in constructors, missing val/var etc.).

To your question: Normally, you can access extension functions even if defined in different kt files. Read the official docs covering extension scopes.

It's important to import your extension function

s1m0nw1
  • 76,759
  • 17
  • 167
  • 196
2

There is a way to do that:

fun <T: Parent> T.toChild2() {
    TODO()
}

Child(...).toChild2()
neworld
  • 7,757
  • 3
  • 39
  • 61
  • You need to declare the generic type parameter before the function name to make it available in the receiver type expression. As explained here: https://kotlinlang.org/docs/extensions.html#extension-functions . – Willey Hute Feb 02 '22 at 07:08