scala的面向对象
面向对象
定义:
是一种编程范式,是相对于面向过程来说的,将数据和方法当成整体来看待 的一种思想,比如:把大象关进冰箱,面向过程来说,就是分为三步,把冰箱打开,把大象放进冰箱,关上冰箱门;而相对于面向对象来说,就可以将冰箱当成一个对象,这个对象可以有开门,放东西,关门等功能,以及属性那:长,宽,高等这些的都可以封装在冰箱这个对象里,这就是面向对象编程
类:具有相同属性和方法的事务(具有相同属性,相同方法的一类对象集合)
对象:类的一个具体的实现
class
一个普通类
定义类
class 类名 创建一个空类,但是可以使用。
class 类名(属性){
属性
方法
}
eg:
使用类
val 实例化对象:类的类型 = new 类名
实例化对象.属性
实例化对象.方法
和java中一样
类参数
在类名的后面可以加小括号,小括号内可以传参数,形式与函数的参数一样,
类属性
在类参数的前面加val或var,类参数直接升级为类属性
不管是类参数还是类属性,new这个类的实例化对象的时候一定需要传参
构造器
主构造器
类本身就是主构造器
辅助构造器
在类的内部以this关键字为方法名的方法
注意:
a.辅助构造器就是一个方法,传参的方式与普通方法一致
b.辅助构造器可以重载
c.每个辅助构造器必须调用其他辅助构造器或主构造器,
最终一定调用主构造器
抽象类
- 一个类中如果存在只声明而没有定义的属性或方法,这个类就是抽象类
- 抽象类不能使用new关键字创建实例化对象,必须由子类继承
- 子类必须重写抽象的属性和方法,可以重写普通属性和方法
- 和Java相同,抽象类中可以定义普通的属性和方法
- 继承子类的参数名与父类的参数名尽量要不一致
- 重写抽象方法前面要加关键字override
内部类
-
在类的内部可以定义一个内部类
-
内部类是属于外部类的实例化对象
-
外部类的属性或参数和内部类的属性或参数尽量不要同名,如果同名,使用 类名.this.xxx 进行区分
-
对内部类和外部类在类内部可以使用 别名 => 设置别名,使用方便
apply
函数名是apply,可以把类的实例化对象当做函数使用,不需要类.方法直接调用
其余与普通函数没有区别
object(对象)
·不能使用new创建实例,实例化对象唯一,相当于java中的单例。
·可以使用object名直接 .属性/方法 使用,相当于java中的静态类。
·在一个文件中,如果class与object同名,
class和object互为伴生关系
class是object的伴生类
object是class的伴生对象
·伴生的好处
a.可以互相访问私有变量
b.直接使用 object名() 获取其伴生类的实例化对象,比较简单,不需要加new。
(List(),Set(),Map()就是Object)
case class 样例类
使用case修改的类,可以默认提供一些方法。
样例类也可以在类中定义普通的属性和方法。
case自动加了伴生对象,样例类,样里面有默认的东西
方法:
a.apply object
b.unapply object
c.hashCode class
d.equles class
e.copy class
f.toString class
trait(特性)
相当于java中的接口,但是可以存在普通方法,一般不使用。
可以实现多重继承的功能
不能使用new关键字创建实例,必须由子类实现
使用with关键字实现接口,有几个trait类需要有几个with
执行顺序
如果一个类继承了普通类,同时实现了多个trail类
当前类的最右侧的那个类为直接父类,向左辈分依次增加
IO读写和jdbc
IO读写
(这里的写与Java中相同,而读不同,读的io是由Source.fromFile获取,返回是BufferedSource)
JDBC
def getConn(): Unit ={
var conn: Connection = null
var ps: PreparedStatement = null
var rs: ResultSet = null
try {
Class.forName("com.mysql.jdbc.Driver")
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/hive", "root", "root")
val sql = "select * from peoples"
ps = conn.prepareStatement(sql)
rs = ps.executeQuery()
while (rs.next()) {
println(rs.getNString("name"))
println(rs.getString("city"))
println("=============================")
}
}catch{
case e:Exception=>println(e)
}finally {
rs.close()
ps.close()
conn.close()
}
}
def main(args: Array[String]): Unit = {
getConn()
}
(这里的代码基本和Java中一样就只是要符合Scala的语法)
隐式转换(implicit)
函数类型
如果当前的参数与需要的参数类型不匹配的时候,
会自动在当前类的所有范围之内(包括import引入的类)查找implicit的方法
如果找到可以转换的方法,自动调用。
按照转换规则查找,与方法名无关
case class SpecialPeople(var name:String)
case class Students(var name:String)
case class Older(var name:String)
object Demo_implicit {
implicit def transform2SpecialPerson(obj:Any):SpecialPeople = {
if(obj.isInstanceOf[Students]){
val stu:Students = obj.asInstanceOf[Students]
SpecialPeople(stu.name)
}else if(obj.isInstanceOf[Older]){
val older:Older = obj.asInstanceOf[Older]
SpecialPeople(older.name)
}else{
null
}
}
def buySpecialTicket(special:SpecialPeople) = {
println(s"${special.name} 买了一张特殊的票")
}
def main(args: Array[String]): Unit = {
val sp = SpecialPeople("wpy")
val stu = Students("wpy")
buySpecialTicket(stu)
}
}
参数类型
如果当前方法的某个参数是以implicit定义的,
调用的时候可以不传递这个参数,会自动找所有的隐式的值或变量,
如果找到,自动传参,按照参数的类型查找,与值或变量的名字无关。
case class Flower(){
def send(name:String) = {
println(s"把花送给${name}")
}
}
object implicit_context{
implicit val flower:Flower = Flower()
}
object Demo_implicit_para {
def sendToGF(name:String)(implicit f:Flower) = {
f.send(name)
}
def sendToBF(name:String)(implicit f:Flower) = {
f.send(name)
}
def main(args: Array[String]): Unit = {
import implicit_context._
sendToGF("wpy")
sendToBF("wpy")
}
}