I was reading the section 20.7 of the book Programming in Scala and I was wondering why while this code compiles:
class Food
class Fish extends Food
class Gr
It's because bessie is declared Animal rather than Cow. bessie.SuitableFood is a "path-dependent type" (see below).
Try this:
val clarabelle: Cow = new Cow
clarabelle eat (new Grass)
This works because the compiler can deduce that clarabelle.SuitableFood = Grass from clarabelle's declared type.
Since bessie is declared Animal, not Cow, the compiler can't safely deduce that bessie.SuitableFood = Grass.* When you say new bessie.SuitableFood, the compiler generates code to look at the actual bessie object and generate a new instance of the appropriate type. bessie.SuitableFood is a "path-dependent type": the "path" (the bessie. part) that leads to the last identifier (SuitableFood) is actually part of the type. This enables you to have a custom version of a type for each individual object of the same class.
*Well, actually, I think that if the compiler were a little smarter, it could deduce that bessie.SuitableFood = Grass, since bessie is a val, not a var, and therefore won't change its type. In other words, the compiler ought to know that even though bessie is declared Animal, she's really a Cow. Perhaps a future version of the compiler will make use of this knowledge, and perhaps there's a good reason why that wouldn't be a good idea, which someone more expert than I will tell us. (Postscript: One just did! See Travis Brown's comment below.)