This post records a sample how I use Scala duck typing(structural types). The posts “here“, “here“ and “here“ are referred.
Let’s say we have the following Scala code which runs properly without any issue.
1 | class Duck { |
The problem happens when I want to refact the code by combining the 3 greeting functions into one:
1 | scala> def greeting(someone: Object): Unit = { |
Scala compiler expects the method “getName()” to be found in the declared type of the given “someone” argument. However the types “Duck/Eagle/Walrus” have no common parent class or interface where the “getName()” method is defined at. In dynamic type languages like “Python/Ruby/JavaScript” this is not an issue since there’s no type checking at compiling time. In static type languages like Java, the “getName()” must be declared at some common parent class or interface which the 3 classes extend or implement. So it seems Scala is one of the static type languages, right? no?
Fortunately, we can do something like below in Scala which doesn’t need to modify the definition of the classes(to add common parent class or interface).
1 | def greeting(someone: Object): Unit = { |
Note the “{def getName: String}” part which plays the trick here. It casts the given instance from the “Object” type to one which has the “getName()” method defined. To me it seems like a placebo to comfort the compiler. Anyway, by doing so the code works as expected. This feature needs “import reflect.Selectable.reflectiveSelectable”. The full code looks like:
1 | import reflect.Selectable.reflectiveSelectable |
Unlike traditional “static typing” languages(like “Java”) or “dynamic typing” languages(like “Python/Ruby/JavaScript”), Scala wants to take advantages from both of them. However, this makes it more complicated than both of them in many scenarios. I think that’s one of the reasons why it’s not very popular nowadays.