-1

This is the simple scala code.

val x: Int = 1000
val y: Any = x

y.toString // returns String = 1000
y.toInt // returns error: value toInt is not a member of Any
y.isInstanceof[Int] // retunrs true

Why y.toInt returns error even though y.isInstanceof[Int] returns true?

Dmytro Mitin
  • 48,194
  • 3
  • 28
  • 66
Koala
  • 11
  • 5
    Because the [`Any`](https://www.scala-lang.org/api/current/scala/Any.html) type does not have any methods called `toInt`, while it *does* have a `toString`. You can't make up method names that don't exist and expect them to work. – Silvio Mayolo Oct 03 '22 at 03:15
  • 5
    @LuisMiguelMejíaSuárez This is a typical mental model of OOP newcomer that I saw before - if I see that value of of some type (since I initiated it) why doesn't compiler sees it? @Koala The answer is that compiler sees only as much as types allows it to. If `1000` is upcasted to `Any` it will see only as much as `Any` has defined. `toInt` is not defined in `Any` so it isn't seen. – Mateusz Kubuszok Oct 03 '22 at 10:06

1 Answers1

1

Consider the following code:

class Parent {
  def parentMethod = println("parent method")
}
class Child extends Parent {
  override def parentMethod = println("parent method overriden")
  def childMethod = println("child method")
}

val p: Parent = new Child
p.isInstanceOf[Child] // true

// p.childMethod // doesn't compile
p.asInstanceOf[Child].childMethod // child method
p.parentMethod // parent method overriden

p has static (compile-time) type Parent but dynamic (runtime) type (class) Child. Which implementation of an instance (virtual) method is chosen is decided based on the runtime class. But whether you are allowed to call a method is decided based on the static type.

Dmytro Mitin
  • 48,194
  • 3
  • 28
  • 66