java面试题网站:www.javaoffers.com
Scala 视图界定,有些书上写的太简,很多细节都没有写到。
先从隐式转换说
隐式转换的启动时机:
掉用成员时 (包括成员变量,成员方法)
传参数时 (实际传入的参数类型与预期的参数类型(声明方法时设定的参数类型)不一致)
隐式转换函数或参数都是存在源(指当前的class)或当前目标的伴生对象中
视图界定:
**************************************案例一**********************************************
package paramtype
class ViewBoundTwo {
def vbt()={
println("this is vbt")
}
}
package paramtype
class ViewBoundOne {
implicit def vo[T](a: T)={
new ViewBoundTwo
}
def say[T](a: T)={
a.vbt()
}
}
object ViewBoundOne{
def main(args: Array[String]): Unit = {
var vbo = new ViewBoundOne
vbo.say()
}
}
**************************************案例二**********************************************
package paramtype
class ViewBoundTwo {
def vbt()={
println("this is vbt")
}
}
package paramtype
class ViewBoundOne {
def say[T](a: T)(implicit f: T=>ViewBoundTwo )={
a.vbt()
}
}
object ViewBoundOne{
implicit def vo[T](a: T)={
new ViewBoundTwo
}
def main(args: Array[String]): Unit = {
var vbo = new ViewBoundOne
vbo.say()
}
}
**************************************案例三**********************************************
package paramtype
class ViewBoundTwo {
def vbt()={
println("this is vbt")
}
}
object ViewBoundTwo{
implicit def vo[T](a: T)={
new ViewBoundTwo
}
}
package paramtype
class ViewBoundOne {
def say[T](a: T)(implicit f: T=>ViewBoundTwo )={
a.vbt()
}
}
object ViewBoundOne{
import paramtype.ViewBoundTwo._
def main(args: Array[String]): Unit = {
var vbo = new ViewBoundOne
vbo.say()
}
}
**************************************案例三视图界定**********************************************
package paramtype
class ViewBoundTwo {
def vbt()={
println("this is vbt")
}
}
object ViewBoundTwo{ //objec伴生对象中编写一个隐式函数
implicit def vo[T](a: T)={
new ViewBoundTwo
}
}
package paramtype
class ViewBoundOne[T <% ViewBoundTwo] {
def say(a: T)={
a.vbt()
}
}
object ViewBoundOne{
def main(args: Array[String]): Unit = {
var vbo = new ViewBoundOne[String]
vbo.say("a")
}
}
**************************************案例四视图界定**********************************************
package paramtype
class ViewBoundTwo {
def vbt()={
println("this is vbt")
}
}
object ViewBoundTwo{// ViewBoundTwo 伴生对象中没有隐式函数
}
package paramtype
class ViewBoundOne[T <% ViewBoundTwo] {
def say(a: T)={
a.vbt()
}
}
object ViewBoundOne{ //ViewBoundOne 伴生对象中编写一个隐式函数
implicit def vo[T](a: T)={
new ViewBoundTwo
}
def main(args: Array[String]): Unit = {
var vbo = new ViewBoundOne[String]
vbo.say("a")
}
}
视图界定是指 T类型可以隐式的转换为 ViewBoundTwo类型,前提条件是在当前目标的伴生对象中或源伴生对象中必须要存在一个
implicit def obj2obj[T](a: T)={
new ViewBoundTwo
}
这样的隐式转换函数。
主语事项:此时在class ViewBoundOne[T <% ViewBoundTwo] 中的方法中不能显示的出现 (implicit f: T=>ViewBoundTwo)柯理化
例如:
def hel(a: T)(implicit f: T=> ViewBoundTwo )={
a.vbt() //这里会报错。因为 T <% ViewBoundTwo 本身就是表达 T 类型可以隐隐式转换成ViewBoundTwo 类型,
//两者的意义是相同的,会形成重复冲突,没有必要。
}
**************************************案例五注意柯理化声明隐式函数**********************************************
package paramtype
class ViewBoundTwo {
def vbt()={
println("this is vbt")
}
}
object ViewBoundTwo{
}
package paramtype
class ViewBoundOne[T] {
implicit def vo[T](a: T)={ //隐式函数 然也可以导入包含此隐式函数的引用 没有实际意义
new ViewBoundTwo
}
def say(a: T)={
a.vbt()
}
def hel(a: T)(implicit f: T=> ViewBoundTwo )={
a.vbt()
}
}
object ViewBoundOne{
implicit def vo[T](a: T)={ //隐式函数 当然也可以导入包含此隐式函数的引用 没有实际意义
new ViewBoundTwo
}
def hel[T](a: T)(implicit f: T=> ViewBoundTwo )={
a.vbt()
}
def main(args: Array[String]): Unit = {
var vbo = new ViewBoundOne[String]
vbo.say("a")
hel("s")
}
}
这个案例你可以看到,在class 中和 object 中 都存在相同的隐式函数 vo,因为在柯理化声明隐式函数的地方必须要保证
此class或object存在对应的实际隐式函数。(implicit f: T=> ViewBoundTwo ) 就是表示此class或object 存在一个实际的
隐式函数 implicit def f‘别名随意’ (a: T)={
new ViewBoundTwo
}
隐式转换的目的就是可以 使当前类型A的参数 可以访问另一种类型B的成员。但是不可以访问B的子类成员。成员:包括成员变量成员方法。