From 76e72cf094ac9316f4f6543b14e0b3c0f892efbc Mon Sep 17 00:00:00 2001 From: tashoyan Date: Wed, 16 Nov 2016 21:09:21 +0300 Subject: [PATCH] Provide better example of upper type bound usage. Previous one was not good, because its code was clearer without type bounds thanks to polymorphism. --- tutorials/tour/upper-type-bounds.md | 44 ++++++++++++++++++----------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/tutorials/tour/upper-type-bounds.md b/tutorials/tour/upper-type-bounds.md index 99d258984b..b344ede3a0 100644 --- a/tutorials/tour/upper-type-bounds.md +++ b/tutorials/tour/upper-type-bounds.md @@ -11,27 +11,39 @@ tutorial-previous: variances --- In Scala, [type parameters](generic-classes.html) and [abstract types](abstract-types.html) may be constrained by a type bound. Such type bounds limit the concrete values of the type variables and possibly reveal more information about the members of such types. An _upper type bound_ `T <: A` declares that type variable `T` refers to a subtype of type `A`. -Here is an example which relies on an upper type bound for the implementation of the polymorphic method `findSimilar`: +Here is an example that demonstrates upper type bound for a type parameter of class `Cage`: ```tut -trait Similar { - def isSimilar(x: Any): Boolean +abstract class Animal { + def name: String } -case class MyInt(x: Int) extends Similar { - def isSimilar(m: Any): Boolean = - m.isInstanceOf[MyInt] && - m.asInstanceOf[MyInt].x == x + +abstract class Pet extends Animal {} + +class Cat extends Pet { + override def name: String = "Cat" +} + +class Dog extends Pet { + override def name: String = "Dog" +} + +class Lion extends Animal { + override def name: String = "Lion" } -object UpperBoundTest extends App { - def findSimilar[T <: Similar](e: T, xs: List[T]): Boolean = - if (xs.isEmpty) false - else if (e.isSimilar(xs.head)) true - else findSimilar[T](e, xs.tail) - val list: List[MyInt] = List(MyInt(1), MyInt(2), MyInt(3)) - println(findSimilar[MyInt](MyInt(4), list)) - println(findSimilar[MyInt](MyInt(2), list)) + +class Cage[P <: Pet](p: P) { + def pet: P = p +} + +object Main extends App { + var dogCage = new Cage[Dog](new Dog) + var catCage = new Cage[Cat](new Cat) + /* Cannot put Lion in a cage as Lion is not a Pet. */ +// var lionCage = new Cage[Lion](new Lion) } ``` -Without the upper type bound annotation it would not be possible to call method `isSimilar` in method `findSimilar`. +An instance of class `Cage` may contain an animal with upper bound `Pet`. An animal of type `Lion` is not a pet and therefore cannot be put into a cage. + The usage of lower type bounds is discussed [here](lower-type-bounds.html).