What is the advantage of using upper type bounds over just type in this example?
Why people prefer this
trait Pages[T <: Page] {
val pages: Seq[T]
def find(id: String): Option[T] = pages.find(_.id == id)
def all: Seq[T] = pages
}
Over this:
trait Pages {
val pages: Seq[Page]
def find(id: String): Option[Page] = pages.find(_.id == id)
def all: Seq[Page] = pages
}
It's the same as the advantage of your second example over
trait Pages {
val pages: Seq[Any]
def find(id: String): Option[Any] = pages.find(_.id == id)
def all: Seq[Any] = pages
}
: more precise types, allowing you not to mix up different subtypes of Page
, to access operations of MyPage
without casting, etc.
Also, if you have the first and need the second, you can just use Pages[Page]
; if you have the second and need the first, you are out of luck.
Ok, I found out that in the first case I can specify type explicitly. If MyPage
is subtype if Page
.
val pages = new Pages[MyPage]{
override val pages: Seq[MyPage] = List(MyPage("a"), MyPage("b"))
}
And the compiler can infer the type so that pages.find("a")
will be the MyPage
type. In the second example the type always will be Page
, which forces to cast it.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.