Created
July 9, 2015 03:34
-
-
Save derekmorr/dd2ae28fdd5aced2d727 to your computer and use it in GitHub Desktop.
Structural typing in Scala
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
case class Circle(radius: Double) { | |
def area = radius * radius * Math.PI | |
} | |
case class Rectangle(side: Double) { | |
def area = side * side | |
} | |
case class Triangle(base: Double, height: Double) { | |
def area = 0.5d * base * height | |
} | |
These classes do not share a common parent type (aside from AnyRef, which is Scala's equivalent of java.lang.Object). They don't implement a common interface. But we can still get strong typing via structural typing -- we declare a dependency on the method they have in common. They each have a method named area which takes no arguments and returns a Double. | |
def areaPrinter(thing: { def area: Double }) = | |
println(s"thing has area ${thing.area}") | |
val circle = Circle(1.0) | |
val triangle = Triangle(1.0, 2.0) | |
val rectangle = Rectangle(4) | |
areaPrinter(circle) | |
areaPrinter(triangle) | |
areaPrinter(rectangle) | |
The parameter thing: { def area: Double } says that the areaPrinter method depends on something with a method named area which takes no arguments and returns a Double. | |
So the above examples would compile, but this would not: | |
areaPrinter("foobar") | |
since String doesn't have an area() method. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment