Skip to content

Instantly share code, notes, and snippets.

@JamesMenetrey
Created October 9, 2017 12:51
Show Gist options
  • Save JamesMenetrey/1c63ba43d1a7f014dc99227c5f7c6e0b to your computer and use it in GitHub Desktop.
Save JamesMenetrey/1c63ba43d1a7f014dc99227c5f7c6e0b to your computer and use it in GitHub Desktop.
Abstract type members in Scala
package scalaInAction.chapter8ScalableExtensibleComponents
import org.scalatest.{FlatSpec, Matchers}
class Food
class Grass extends Food
abstract class Animal {
type SuitableFood <: Food // Upper bound (<:)
def eat(food: SuitableFood): String
def create: SuitableFood
}
class Cow extends Animal {
type SuitableFood = Grass
override def eat(food: SuitableFood): String = s"The cow eats ${food.getClass.getSimpleName}."
def create: SuitableFood = new SuitableFood // underlying Grass
}
object ComplexFactory {
def get: Animal = new Cow
}
class AbstractTypeMembers extends FlatSpec with Matchers {
"Abstract type members" can "returns its abstract type to reference compatible types" in {
val cow: Cow = new Cow
val grass: cow.SuitableFood = new Grass
cow.eat(grass)
}
"Abstract type members" can "wisely understand that types passed by argument are compatible with their abstract types." in {
val cow: Cow = new Cow
cow.eat(new Grass)
}
"Abstract type members" must "be type-safe, by checking the type of the argument" in {
val cow: Cow = new Cow
// Can't compile because a cow cannot eat any type of Food
"cow.eat(new Food)" shouldNot compile
}
"Abstract type members" must "enforce the abstract type when the variable is not of the type of the underlying class" in {
val cowAsAnimal: Animal = new Cow
// Can't compile because an animal can only eat a SuitableFood
"cowAsAnimal.eat(new Food)" shouldNot compile
"cowAsAnimal.eat(new Grass)" shouldNot compile
}
"Abstract type members" can "return method dependent types are handle them back" in {
val cowAsAnimal: Animal = new Cow
val foodForCow: cowAsAnimal.SuitableFood = cowAsAnimal.create
cowAsAnimal.eat(foodForCow) should be ("The cow eats Grass.")
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment