一.隐式参数和隐式值
- 用法如下:
package Implicit
object ImplicitDemo_value_parameter {
def main(args: Array[String]): Unit = {
//声明隐式值,注意同种类型只能声明一个值,否则运行错误(ambiguous--模糊的无法确定到底引用哪个值)
implicit val x = 1
implicit val y = "hello implicit"
//隐式参数必须使用函数柯里化,且在函数参数列表最后一项,只可有一个implicit关键字修饰
//隐式参数可有默认值,其优先级为:传指定参数>隐式值>默认值
def showMsg(a:Int,b:Int)(implicit x1:Int=2,y1:String="hello"):Int={println(y1);a+b+x1}
//调用时不传参数,优先使用隐式值
println(showMsg(1, 2))//hello implicit 换行 4
//调用时传入参数,优先级最大
println(showMsg(1, 2)(7,"Hello Implicit"))//Hello Implicit 换行 10
}
}
二.隐式函数,又称隐式转换,用于类型不匹配时自动转换类型或关联两个类(即类型增强)
package Implicit
class Person {
def showMsg={println("我是一个人")}
}
class ImplicitDemo_function
object ImplicitDemo_function {
def main(args: Array[String]): Unit = {
//val s:Int =1.5 这种声明如果不写隐式转换函数,会直接报错,如果定义了隐式转换函数就可以自动转换为Int
//定义转换函数需要根据需求来写,比如上面的例子需要把Double类型转化为Int类型
implicit def double2int(x:Double):Int=x.toInt
val s:Int = 1.5
//隐式转换函数也可使得两个毫无关系的类之间关联起来,也叫类型增强如下:
implicit def demoToPerson(x:ImplicitDemo_function):Person=new Person
val demo = new ImplicitDemo_function
//因为使用了隐式函数关联,可直接使用Person类的方法,这样两个毫无关系的类就可关联起来了,可随心所欲的扩展
demo.showMsg//我是一个人
}
}
三.隐式类
注意:隐式类只能声明在object中
举个例子详细说明隐式类的方法:使用jdbc连接mysql
1.定义隐式类
package MysqlUtil
import java.sql.{Connection, DriverManager, PreparedStatement, ResultSet}
import mysqldemo.MysqlPractice
object MySQLUtils {
//声明隐式类必须在object中且构造方法需要有一个类作为参数,当new该类对象的时候只要导了该隐式类,就可使用隐式类的所有方法
implicit class MySQLOP(obj:MysqlPractice){ //定义连接jdbc的隐式类
//定义相关变量
private val driver = "com.mysql.jdbc.Driver"//驱动
private var connection : Connection = _//连接
private var pstm : PreparedStatement = _//会话管理器
private var rs : ResultSet = _//结果集
//获取链接
def conn():Connection={
//加载驱动
Class.forName(driver)
//获取连接
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/test","root","sunyong")
connection
}
//查询结果集
def query(sql:String,param:Object*):ResultSet ={
//获取连接
conn()
//使用连接获取会话管理器
pstm=connection.prepareStatement(sql)
//设置sql语句参数
for (i<-0 until param.length) pstm.setObject(i+1,param(i))
//执行查询
rs=pstm.executeQuery()
rs
}
//增删改
def update(sql:String,params:Object*):Int = {
//获取连接
conn()
//创建sql会话管理器
pstm=connection.prepareStatement(sql)
//设置sql语句参数
for(i<- 0 until params.length) pstm.setObject(i+1,params(i))
//执行语句
pstm.executeUpdate()
}
//关闭资源
def close() = {
if (rs!=null) rs=null
if (pstm!=null) pstm=null
if(connection!=null) connection=null
}
}
}
2.创建隐式类的参数类型对象,调用隐式类方法
package mysqldemo
class MysqlPractice {
}
object MysqlPractice{
def main(args: Array[String]): Unit = {
//导包需要导到哪?-->必须导到隐式类所在的object对象中(或者进一步细化到该隐式类)
// -->因为隐式类不允许写在顶级类上
import MysqlUtil.MySQLUtils._ //或import MysqlUtil.MySQLUtils.MySQLOP
//创建隐式类参数类型的对象
val practice = new MysqlPractice
//执行隐式类的方法
val rs = practice.query("select * from student")
while(rs.next()){
// var name:String=rs.getString("name");
var sex:String=rs.getString("sex");
var age:String=rs.getString("age");
println(sex+" "+age)
}
practice.close()
}
}
效果如下: