Is there a way for me to strip an object of all pr...
# getting-started
r
Is there a way for me to strip an object of all properties/functions associated with an interface (trait)? And also add traits on the fly
Copy code
interface Trait1 {
  foo() { printn(5) }
}
interface Trait2 {
  bar() { printn(7) }
}
class X : Trait1, Trait2

var x = X()
x.foo() // works!
x.bar() // works!
// later...
x = x.remove(Trait1)
x.foo() // alert! does not exist on type!
x.bar() // works still!
x = x.add(Trait1)
x.foo() // works again!
j
You can play with the static type of the reference variables you're working with.
val x = X()
infers the type of
x
to
X
, so it implements both
Trait1
and
Trait2
(+
X
-specific things). If you declare another variable with an explicit static type you can reduce this:
Copy code
val x = X()

val y: Trait1 = x
The variable
y
still points to the same instance of
X
as the
x
variable, but accesses through
y
can only use
Trait1
operations.
The reverse operation is unsafe, but possible. When you get
y
from somewhere, and you somehow know that it must really be an
X
inside, you could cast it back to
X
to get the properties again:
Copy code
val x2 = y as X // fails at runtime if y was not an instance of X

val x3 = y as? X // yields null if y was not an instance of X
Something that must be made clear is that the value of the instance of
X()
that you created initially doesn't change in any way. The only thing that changes is the static type of the reference variables that point to that instance of
X
. The compiler only cares about this for static analysis.
r
@Joffrey in this case of an object that currently inherits 6 traits, and I only want to "erase" 1 out of the 6, this would require me manually re-annotating the 5 types right?
(I also will not necessarily know what the other traits are when doing this)
j
There is no way to express this as a subtraction in Kotlin (to my knowledge). What you could do is declare a common interface as a parent for the group of traits you do want. If you have a need to deal with the group of 5 interfaces differently from the 6th, there is probably a name you could give to that group / a common property they share or something that could warrant having a common interface. This way you can have the common properties/operations that you want to perform on your 5-traited variable. Just having the group on interfaces as a union wouldn't give you anything useful otherwise anyway.