``` abstract class A() class B(): A() class C(): A...
# announcements
r
Copy code
abstract class A()
class B(): A()
class C(): A()

fun foo(b: B)
fun foo(c: C)
If I have something like this, a base class with subclasses and overloaded functions, what is the "best" way to call it IF they are stored in a variable of type A?
Copy code
class Something(val member: A)

val v = Something(B())

foo(v.member) // How to get this to call the right foo
d
foo(a as B)
Copy code
if (a is B) {
    foo(a)
}
n
You want polymorphism on the concrete subclass of A. So make
foo
an abstract method in A, with implementations in
B
and
C
you can make
foo(a)
call the method, if you don’t want the change to impact existing client code
r
that seems "better" than having a big when switch
however that forces the functions to be public
n
Or…
Make A a sealed class
Then foo can use an exhaustive
when
expression to switch on the subtype of A. That way the compiler tells you if
foo
no longer handles all subclasses of A if you add a new one
d
I though your
foo
is a top level function
r
This results in something like:
Copy code
when (v) {
is B -> foo(v)
is C -> foo(v)
is D -> foo(v)
}
is there no better way?
d
If
foo
are top level functions no
n
It depends on your trade-offs
d
However if you can modify the classes, you could use a visitor pattern
Or just delegate the calls directly from an abstract function
n
In kotlin you either have polymorphic methods or algebraic data types (sealed classes in Kotlin syntax). Polymorphic methods make it easier to add new subtypes, but harder to add new operations. Sealed classes make it easier to add new operations but harder to add new subtypes.
So one has to choose between them depending on what is most likely to vary in your system.
r
Alright thanks
d
Sealed classes are just abstract classes
n
(This dichotomy is called the Expression Problem in computer science literature. Some languages have mechanisms to address this, such as type classes, but Kotlin doesn’t right now and maybe never will)
d
Algebraic data types?
I dont believe that's a thing in kotlin
And polymorphic methods- are you talking about virtual functions?
Sorry I'm just confused
n
Sealed classes are Kotlin’s mechanism for defining algebraic data types. “Algebraic data type” is the concept. Sealed classes is Kotlin’s syntax for that.
Yes. Kotlin doesn’t have the concept of “virtual functions” like, say, C++ does. Instead if has methods that can be “abstract” or “open”. In both cases (C++ virtual functions, Kotlin’s open methods), the method call is polymorphic — it can do different things if called on different concrete types.
d
open and virtual functions are intervhangeavle terms
And I think it would be more accurate to say that algebraic data types could be an application of sealed classes right?
n
Or maybe that a sealed class hierarchy forms an algebraic data type.
d
I dont want to dive into a discussion